diff --git a/command.c b/command.c
index 5bdf55e..36f8f9e 100644
--- a/command.c
+++ b/command.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 17+
+This version is for pigpio version 18+
*/
#include
@@ -411,7 +411,7 @@ static errInfo_t errInfo[]=
{PI_BAD_WVSC_COMMND , "bad WVSC subcommand"},
{PI_BAD_WVSM_COMMND , "bad WVSM subcommand"},
{PI_BAD_WVSP_COMMND , "bad WVSP subcommand"},
- {PI_BAD_PULSELEN , "trigger pulse > 50 microseconds"},
+ {PI_BAD_PULSELEN , "trigger pulse > 100 microseconds"},
{PI_BAD_SCRIPT , "invalid script"},
{PI_BAD_SCRIPT_ID , "unknown script id"},
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
diff --git a/pigpio.3 b/pigpio.3
index 533bb46..a5efe76 100644
--- a/pigpio.3
+++ b/pigpio.3
@@ -2363,8 +2363,10 @@ PI_I2C_WRITE_FAILED.
.IP "\fBint spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)\fP"
.IP "" 4
-This function returns a handle for the SPI device on the channel
-Data will be transferred at baud bits per second.
+This function returns a handle for the SPI device on the channel.
+Data will be transferred at baud bits per second. The flags may
+be used to modify the default behaviour of 4-wire operation, mode 0,
+active low chip select.
.br
@@ -2375,7 +2377,7 @@ Data will be transferred at baud bits per second.
.br
spiBaud: >1
.br
-spiFlags: 0-3
+spiFlags: 0-0xFF
.br
.EE
@@ -2389,7 +2391,24 @@ PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
.br
.br
-The least significant two bits of flags define the SPI mode.
+spiFlags consists of the least significant 8 bits.
+
+.br
+
+.br
+
+.EX
+7 6 5 4 3 2 1 0
+.br
+n n n n W P m m
+.br
+
+.EE
+
+.br
+
+.br
+mm defines the SPI mode.
.br
@@ -2411,6 +2430,23 @@ Mode POL PHA
.br
+.br
+P is 0 for active low chip select (normal) and 1 for active high.
+
+.br
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+
+.br
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+.br
+
.br
The other bits in flags should be set to zero.
@@ -5483,8 +5519,64 @@ A SPI channel, 0 or 1.
.br
.br
-Flags which modify a SPI open command. The two least significant bits
-define the SPI mode. The other bits are undefined.
+spiFlags consists of the least significant 8 bits.
+
+.br
+
+.br
+
+.EX
+7 6 5 4 3 2 1 0
+.br
+n n n n W P m m
+.br
+
+.EE
+
+.br
+
+.br
+mm defines the SPI mode.
+
+.br
+
+.br
+
+.EX
+Mode POL PHA
+.br
+ 0 0 0
+.br
+ 1 0 1
+.br
+ 2 1 0
+.br
+ 3 1 1
+.br
+
+.EE
+
+.br
+
+.br
+P is 0 for active low chip select (normal) and 1 for active high.
+
+.br
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+
+.br
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+.br
+
+.br
+The other bits in flags should be set to zero.
.br
@@ -5992,7 +6084,7 @@ A 16-bit word value.
.br
#define PI_BAD_WVSP_COMMND -45 // bad WVSP subcommand
.br
-#define PI_BAD_PULSELEN -46 // trigger pulse length > 50
+#define PI_BAD_PULSELEN -46 // trigger pulse length > 100
.br
#define PI_BAD_SCRIPT -47 // invalid script
.br
diff --git a/pigpio.c b/pigpio.c
index 0bd05f9..aae1355 100644
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* pigpio version 17 */
+/* pigpio version 18 */
#include
#include
@@ -54,7 +54,6 @@ For more information, please refer to
#include
#include
#include
-#include
#include "pigpio.h"
@@ -293,17 +292,18 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define GPIO_BASE 0x20200000
#define PCM_BASE 0x20203000
#define PWM_BASE 0x2020C000
-#define SPI0_BASE 0x20204000
+#define SPI_BASE 0x20204000
#define SYST_BASE 0x20003000
#define UART0_BASE 0x20201000
#define UART1_BASE 0x20215000
-#define DMA_LEN 0x1000 /* allow access to all channels */
#define CLK_LEN 0xA8
+#define DMA_LEN 0x1000 /* allow access to all channels */
#define GPIO_LEN 0xB4
-#define SYST_LEN 0x1C
#define PCM_LEN 0x24
#define PWM_LEN 0x28
+#define SPI_LEN 0x18
+#define SYST_LEN 0x1C
#define DMA_ENABLE (0xFF0/4)
@@ -482,6 +482,59 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define SYST_CLO 1
#define SYST_CHI 2
+/* SPI */
+
+#define SPI_CS 0
+#define SPI_FIFO 1
+#define SPI_CLK 2
+#define SPI_DLEN 3
+#define SPI_LTOH 4
+#define SPI_DC 5
+
+#define SPI_CS_LEN_LONG (1<<25)
+#define SPI_CS_DMA_LEN (1<<24)
+#define SPI_CS_CSPOL2 (1<<23)
+#define SPI_CS_CSPOL1 (1<<22)
+#define SPI_CS_CSPOL0 (1<<21)
+#define SPI_CS_RXF (1<<20)
+#define SPI_CS_RXR (1<<19)
+#define SPI_CS_TXD (1<<18)
+#define SPI_CS_RXD (1<<17)
+#define SPI_CS_DONE (1<<16)
+#define SPI_CS_LEN (1<<13)
+#define SPI_CS_REN (1<<12)
+#define SPI_CS_ADCS (1<<11)
+#define SPI_CS_INTR (1<<10)
+#define SPI_CS_INTD (1<<9)
+#define SPI_CS_DMAEN (1<<8)
+#define SPI_CS_TA (1<<7)
+#define SPI_CS_CSPOL(x) ((x)<<6)
+#define SPI_CS_CLEAR(x) ((x)<<4)
+#define SPI_CS_MODE(x) ((x)<<2)
+#define SPI_CS_CS(x) ((x)<<0)
+
+#define SPI_DC_RPANIC(x) ((x)<<24)
+#define SPI_DC_RDREQ(x) ((x)<<16)
+#define SPI_DC_TPANIC(x) ((x)<<8)
+#define SPI_DC_TDREQ(x) ((x)<<0)
+
+#define SPI_MODE0 0
+#define SPI_MODE1 1
+#define SPI_MODE2 2
+#define SPI_MODE3 3
+
+#define SPI_CS0 0
+#define SPI_CS1 1
+#define SPI_CS2 2
+
+/* SPI gpios. */
+
+#define PI_SPI_CE0 8
+#define PI_SPI_CE1 7
+#define PI_SPI_SCLK 11
+#define PI_SPI_MISO 9
+#define PI_SPI_MOSI 10
+
/* --------------------------------------------------------------- */
#define NORMAL_DMA (DMA_NO_WIDE_BURSTS | DMA_WAIT_RESP)
@@ -570,8 +623,6 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define SRX_BUF_SIZE 8192
-#define MAX_DELAY 50
-
#define PI_I2C_SLAVE 0x0703
#define PI_I2C_SMBUS 0x0720
@@ -726,7 +777,6 @@ typedef struct
typedef struct
{
uint16_t state;
- int16_t fd;
unsigned speed;
uint32_t flags;
} spiInfo_t;
@@ -937,6 +987,7 @@ static volatile uint32_t * dmaReg = MAP_FAILED;
static volatile uint32_t * gpioReg = MAP_FAILED;
static volatile uint32_t * pcmReg = MAP_FAILED;
static volatile uint32_t * pwmReg = MAP_FAILED;
+static volatile uint32_t * spiReg = MAP_FAILED;
static volatile uint32_t * systReg = MAP_FAILED;
static volatile uint32_t * dmaIn = MAP_FAILED;
@@ -1057,7 +1108,7 @@ static uint32_t myGpioDelay(uint32_t micros)
start = systReg[SYST_CLO];
- if (micros <= MAX_DELAY) while ((systReg[SYST_CLO] - start) <= micros);
+ if (micros <= PI_MAX_BUSY_DELAY) while ((systReg[SYST_CLO] - start) <= micros);
else myGpioSleep(micros/MILLION, micros%MILLION);
@@ -2801,31 +2852,187 @@ int i2cClose(unsigned handle)
/* ======================================================================= */
+static unsigned old_mode_ce0;
+static unsigned old_mode_ce1;
+static unsigned old_mode_sclk;
+static unsigned old_mode_miso;
+static unsigned old_mode_mosi;
+
+static uint32_t old_spi_cs;
+static uint32_t old_spi_clk;
+
+static uint32_t spi_dummy; /* only used to prevent warning */
+
+static void spiInit(void)
+{
+ 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);
+
+ gpioSetMode(PI_SPI_CE0, PI_ALT0);
+ gpioSetMode(PI_SPI_CE1, PI_ALT0);
+ gpioSetMode(PI_SPI_SCLK, PI_ALT0);
+ gpioSetMode(PI_SPI_MISO, PI_ALT0);
+ gpioSetMode(PI_SPI_MOSI, PI_ALT0);
+
+ old_spi_cs = spiReg[SPI_CS];
+ old_spi_clk = spiReg[SPI_CLK];
+}
+
+static void spiTerm(void)
+{
+ gpioSetMode(PI_SPI_CE0, old_mode_ce0);
+ 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;
+}
+
+#define PI_SPI_FLAGS_CHAN(x) ((x)<<30)
+
+/*
+3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+C C - - - - - - - - - - - - - - - - - - - - - - N N N N 3 P M M
+
+CC channel
+NNNN switch to 3-wire after NNNN bytes
+3 3-wire part
+P CS polarity
+MM mode
+*/
+static void spiGo(
+ unsigned speed,
+ uint32_t flags,
+ char *txBuf,
+ char *rxBuf,
+ unsigned count)
+{
+ unsigned txCnt=0;
+ unsigned rxCnt=0;
+ unsigned cnt, cnt4w, cnt3w;
+ uint32_t spiDefaults;
+ unsigned mode, channel, cspol, flag3w, ren3w;
+
+ mode = flags & 3;
+ cspol = (flags >> 2) & 1;
+ flag3w = (flags >> 3) & 1;
+ ren3w = (flags >> 4) & 15;
+ channel = (flags >> 30) & 3;
+
+ spiDefaults = SPI_CS_MODE(mode) |
+ SPI_CS_CS(channel) |
+ SPI_CS_CSPOL(cspol) |
+ SPI_CS_CLEAR(3);
+
+ if (flag3w)
+ {
+ if (ren3w < count)
+ {
+ cnt4w = ren3w;
+ cnt3w = count - ren3w;
+ }
+ else
+ {
+ cnt4w = count;
+ cnt3w = 0;
+ }
+ }
+ else
+ {
+ cnt4w = count;
+ cnt3w = 0;
+ }
+
+ spiReg[SPI_CLK] = 250000000/speed;
+
+ spiReg[SPI_CS] = spiDefaults | SPI_CS_TA; /* start */
+
+ cnt = cnt4w;
+
+ while((txCnt < cnt) || (rxCnt < cnt))
+ {
+ while((txCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_TXD)))
+ {
+ if (txBuf) spiReg[SPI_FIFO] = txBuf[txCnt];
+ else spiReg[SPI_FIFO] = 0;
+ txCnt++;
+ }
+
+ while((rxCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_RXD)))
+ {
+ if (rxBuf) rxBuf[rxCnt] = spiReg[SPI_FIFO];
+ else spi_dummy = spiReg[SPI_FIFO];
+ rxCnt++;
+ }
+ }
+
+ while (!(spiReg[SPI_CS] & SPI_CS_DONE)) ;
+
+ /* now switch to 3-wire bus */
+
+ cnt += cnt3w;
+
+ while((txCnt < cnt) || (rxCnt < cnt))
+ {
+ spiReg[SPI_CS] |= SPI_CS_REN;
+
+ while((txCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_TXD)))
+ {
+ if (txBuf) spiReg[SPI_FIFO] = txBuf[txCnt];
+ else spiReg[SPI_FIFO] = 0;
+ txCnt++;
+ }
+
+ while((rxCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_RXD)))
+ {
+ if (rxBuf) rxBuf[rxCnt] = spiReg[SPI_FIFO];
+ else spi_dummy = spiReg[SPI_FIFO];
+ rxCnt++;
+ }
+ }
+
+ while (!(spiReg[SPI_CS] & SPI_CS_DONE)) ;
+
+ spiReg[SPI_CS] = spiDefaults; /* stop */
+}
+
+static int spiAnyOpen(void)
+{
+ int i;
+
+ for (i=0; i= PI_NUM_SPI_CHANNEL)
SOFT_ERROR(PI_BAD_SPI_CHANNEL, "bad spiChan (%d)", spiChan);
if (!spiBaud)
SOFT_ERROR(PI_BAD_SPI_SPEED, "bad spiBaud (%d)", spiBaud);
- if (spiFlags > 3)
+ if (spiFlags > 256)
SOFT_ERROR(PI_BAD_FLAGS, "bad spiFlags (0x%X)", spiFlags);
+ if (!spiAnyOpen()) spiInit(); /* initialise on first open */
+
slot = -1;
for (i=0; i= 0) close(spiInfo[handle].fd);
-
- spiInfo[handle].fd = -1;
spiInfo[handle].state = PI_I2C_CLOSED;
+ if (!spiAnyOpen()) spiTerm(); /* terminate on last close */
+
return 0;
}
int spiRead(unsigned handle, char *buf, unsigned count)
{
- int err;
-
- struct spi_ioc_transfer spi;
-
DBG(DBG_USER, "handle=%d count=%d [%s]",
handle, count, myBuf2Str(count, buf));
@@ -2926,25 +3089,13 @@ int spiRead(unsigned handle, char *buf, unsigned count)
if ((count < 1) || (count > PI_MAX_SPI_DEVICE_COUNT))
SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
- spi.tx_buf = (unsigned) NULL;
- spi.rx_buf = (unsigned) buf;
- spi.len = count;
- spi.speed_hz = spiInfo[handle].speed;
- spi.delay_usecs = 0;
- spi.bits_per_word = 8;
- spi.cs_change = 0;
+ spiGo(spiInfo[handle].speed, spiInfo[handle].flags, NULL, buf, count);
- err = ioctl(spiInfo[handle].fd, SPI_IOC_MESSAGE(1), &spi);
-
- if (err < 0) return PI_SPI_XFER_FAILED;
- else return err;
+ return count;
}
int spiWrite(unsigned handle, char *buf, unsigned count)
{
- int err;
- struct spi_ioc_transfer spi;
-
DBG(DBG_USER, "handle=%d count=%d [%s]",
handle, count, myBuf2Str(count, buf));
@@ -2959,25 +3110,13 @@ int spiWrite(unsigned handle, char *buf, unsigned count)
if ((count < 1) || (count > PI_MAX_SPI_DEVICE_COUNT))
SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
- spi.tx_buf = (unsigned) buf;
- spi.rx_buf = (unsigned) NULL;
- spi.len = count;
- spi.speed_hz = spiInfo[handle].speed;
- spi.delay_usecs = 0;
- spi.bits_per_word = 8;
- spi.cs_change = 0;
+ spiGo(spiInfo[handle].speed, spiInfo[handle].flags, buf, NULL, count);
- err = ioctl(spiInfo[handle].fd, SPI_IOC_MESSAGE(1), &spi);
-
- if (err < 0) return PI_SPI_XFER_FAILED;
- else return err;
+ return count;
}
int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)
{
- int err;
- struct spi_ioc_transfer spi;
-
DBG(DBG_USER, "handle=%d count=%d [%s]",
handle, count, myBuf2Str(count, txBuf));
@@ -2992,18 +3131,9 @@ int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)
if ((count < 1) || (count > PI_MAX_SPI_DEVICE_COUNT))
SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
- spi.tx_buf = (unsigned long)txBuf;
- spi.rx_buf = (unsigned long)rxBuf;
- spi.len = count;
- spi.speed_hz = spiInfo[handle].speed;
- spi.delay_usecs = 0;
- spi.bits_per_word = 8;
- spi.cs_change = 0;
+ spiGo(spiInfo[handle].speed, spiInfo[handle].flags, txBuf, rxBuf, count);
- err = ioctl(spiInfo[handle].fd, SPI_IOC_MESSAGE(1), &spi);
-
- if (err < 0) return PI_SPI_XFER_FAILED;
- else return err;
+ return count;
}
/* ======================================================================= */
@@ -4562,17 +4692,28 @@ static void *pthSocketThreadHandler(void *fdC)
buf[p[3]] = 0;
- if (p[0] != PI_CMD_NOIB)
+ switch (p[0])
{
- p[3] = myDoCommand(p, sizeof(buf)-1, buf);
- }
- else
- {
- p[3] = gpioNotifyOpenInBand(sock);
+ case PI_CMD_NOIB:
+ p[3] = gpioNotifyOpenInBand(sock);
- /* Enable the Nagle algorithm. */
- opt = 0;
- setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
+ /* Enable the Nagle algorithm. */
+ opt = 0;
+ setsockopt(
+ sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
+ break;
+
+ case PI_CMD_PROCP:
+ p[3] = myDoCommand(p, sizeof(buf)-1, buf+sizeof(int));
+ if (p[3] >= 0)
+ {
+ memcpy(buf, &p[3], 4);
+ p[3] = 4 + (4*PI_MAX_SCRIPT_PARAMS);
+ }
+ break;
+
+ default:
+ p[3] = myDoCommand(p, sizeof(buf)-1, buf);
}
write(sock, p, 16);
@@ -4585,6 +4726,7 @@ static void *pthSocketThreadHandler(void *fdC)
case PI_CMD_I2CRD:
case PI_CMD_I2CRI:
case PI_CMD_I2CRK:
+ case PI_CMD_PROCP:
case PI_CMD_SERR:
case PI_CMD_SLR:
case PI_CMD_SPIX:
@@ -4596,14 +4738,6 @@ static void *pthSocketThreadHandler(void *fdC)
}
break;
- case PI_CMD_PROCP:
-
- if (p[3] >= 0)
- {
- write(sock, buf, sizeof(uint32_t)*PI_MAX_SCRIPT_PARAMS);
- }
- break;
-
default:
break;
}
@@ -4830,6 +4964,11 @@ static int initPeripherals(void)
if (systReg == MAP_FAILED)
SOFT_ERROR(PI_INIT_FAILED, "mmap syst failed (%m)");
+ spiReg = initMapMem(fdMem, SPI_BASE, SPI_LEN);
+
+ if (spiReg == MAP_FAILED)
+ SOFT_ERROR(PI_INIT_FAILED, "mmap spi failed (%m)");
+
pwmReg = initMapMem(fdMem, PWM_BASE, PWM_LEN);
if (pwmReg == MAP_FAILED)
@@ -5298,6 +5437,7 @@ static void initClearGlobals(void)
pcmReg = MAP_FAILED;
pwmReg = MAP_FAILED;
systReg = MAP_FAILED;
+ spiReg = MAP_FAILED;
}
/* ----------------------------------------------------------------------- */
@@ -5351,6 +5491,7 @@ static void initReleaseResources(void)
if (pcmReg != MAP_FAILED) munmap((void *)pcmReg, PCM_LEN);
if (pwmReg != MAP_FAILED) munmap((void *)pwmReg, PWM_LEN);
if (systReg != MAP_FAILED) munmap((void *)systReg, SYST_LEN);
+ if (spiReg != MAP_FAILED) munmap((void *)spiReg, SPI_LEN);
clkReg = MAP_FAILED;
dmaReg = MAP_FAILED;
@@ -5358,6 +5499,7 @@ static void initReleaseResources(void)
pcmReg = MAP_FAILED;
pwmReg = MAP_FAILED;
systReg = MAP_FAILED;
+ spiReg = MAP_FAILED;
if (dmaVirt != MAP_FAILED)
{
@@ -7132,7 +7274,7 @@ int gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
if (level > PI_ON)
SOFT_ERROR(PI_BAD_LEVEL, "gpio %d, bad level (%d)", gpio, level);
- if ((pulseLen > PI_MAX_PULSELEN) || (!pulseLen))
+ if ((pulseLen > PI_MAX_BUSY_DELAY) || (!pulseLen))
SOFT_ERROR(PI_BAD_PULSELEN,
"gpio %d, bad pulseLen (%d)", gpio, pulseLen);
@@ -7476,7 +7618,7 @@ int gpioScriptStatus(unsigned script_id, uint32_t *param)
if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
{
- if (param != 0)
+ if (param != NULL)
{
memcpy(param, gpioScript[script_id].script.par,
sizeof(uint32_t) * PI_MAX_SCRIPT_PARAMS);
@@ -7773,7 +7915,7 @@ uint32_t gpioDelay(uint32_t micros)
start = systReg[SYST_CLO];
- if (micros <= MAX_DELAY) while ((systReg[SYST_CLO] - start) <= micros);
+ if (micros <= PI_MAX_BUSY_DELAY) while ((systReg[SYST_CLO] - start) <= micros);
else gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION));
diff --git a/pigpio.h b/pigpio.h
index 91ae30a..f9f0916 100644
--- a/pigpio.h
+++ b/pigpio.h
@@ -31,7 +31,7 @@ For more information, please refer to
#include
#include
-#define PIGPIO_VERSION 17
+#define PIGPIO_VERSION 18
/*TEXT
@@ -481,10 +481,11 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_WAVE_MODE_ONE_SHOT 0
#define PI_WAVE_MODE_REPEAT 1
-#define PI_I2C_SLOTS 32
-#define PI_SPI_SLOTS 4
-#define PI_SER_SLOTS 4
+/* I2C, SPI, SER */
+#define PI_I2C_SLOTS 32
+#define PI_SPI_SLOTS 8
+#define PI_SER_SLOTS 8
#define PI_NUM_I2C_BUS 2
#define PI_NUM_SPI_CHANNEL 2
@@ -492,7 +493,14 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_MAX_I2C_DEVICE_COUNT 8192
#define PI_MAX_SPI_DEVICE_COUNT 8192
-#define PI_MAX_PULSELEN 50
+#define PI_SPI_FLAGS_3WREN(x) ((x)<<4)
+#define PI_SPI_FLAGS_3WIRE(x) ((x)<<3)
+#define PI_SPI_FLAGS_CSPOL(x) ((x)<<2)
+#define PI_SPI_FLAGS_MODE(x) ((x)<<0)
+
+/* Longest busy delay */
+
+#define PI_MAX_BUSY_DELAY 100
/* timeout: 0-60000 */
@@ -1873,19 +1881,28 @@ D*/
/*F*/
int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags);
/*D
-This function returns a handle for the SPI device on the channel
-Data will be transferred at baud bits per second.
+This function returns a handle for the SPI device on the channel.
+Data will be transferred at baud bits per second. The flags may
+be used to modify the default behaviour of 4-wire operation, mode 0,
+active low chip select.
. .
spiChan: 0-1
spiBaud: >1
-spiFlags: 0-3
+spiFlags: 0-0xFF
. .
Returns a handle (>=0) if OK, otherwise PI_BAD_SPI_CHANNEL,
PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
-The least significant two bits of flags define the SPI mode.
+spiFlags consists of the least significant 8 bits.
+
+. .
+7 6 5 4 3 2 1 0
+n n n n W P m m
+. .
+
+mm defines the SPI mode.
. .
Mode POL PHA
@@ -1895,6 +1912,14 @@ Mode POL PHA
3 1 1
. .
+P is 0 for active low chip select (normal) and 1 for active high.
+
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
The other bits in flags should be set to zero.
D*/
@@ -3521,8 +3546,32 @@ A SPI channel, 0 or 1.
spiFlags::
-Flags which modify a SPI open command. The two least significant bits
-define the SPI mode. The other bits are undefined.
+spiFlags consists of the least significant 8 bits.
+
+. .
+7 6 5 4 3 2 1 0
+n n n n W P m m
+. .
+
+mm defines the SPI mode.
+
+. .
+Mode POL PHA
+ 0 0 0
+ 1 0 1
+ 2 1 0
+ 3 1 1
+. .
+
+P is 0 for active low chip select (normal) and 1 for active high.
+
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+The other bits in flags should be set to zero.
spiSS::
@@ -3809,7 +3858,7 @@ after this command is issued.
#define PI_BAD_WVSC_COMMND -43 // bad WVSC subcommand
#define PI_BAD_WVSM_COMMND -44 // bad WVSM subcommand
#define PI_BAD_WVSP_COMMND -45 // bad WVSP subcommand
-#define PI_BAD_PULSELEN -46 // trigger pulse length > 50
+#define PI_BAD_PULSELEN -46 // trigger pulse length > 100
#define PI_BAD_SCRIPT -47 // invalid script
#define PI_BAD_SCRIPT_ID -48 // unknown script id
#define PI_BAD_SER_OFFSET -49 // add serial data offset > 30 minutes
diff --git a/pigpio.py b/pigpio.py
index a20a4bc..184255e 100644
--- a/pigpio.py
+++ b/pigpio.py
@@ -246,7 +246,7 @@ import os
import atexit
import codecs
-VERSION = "1.7"
+VERSION = "1.8"
exceptions = True
@@ -532,7 +532,7 @@ _errors=[
[PI_BAD_WVSC_COMMND , "bad WVSC subcommand"],
[PI_BAD_WVSM_COMMND , "bad WVSM subcommand"],
[PI_BAD_WVSP_COMMND , "bad WVSP subcommand"],
- [PI_BAD_PULSELEN , "trigger pulse length > 50"],
+ [PI_BAD_PULSELEN , "trigger pulse length > 100"],
[PI_BAD_SCRIPT , "invalid script"],
[PI_BAD_SCRIPT_ID , "unknown script id"],
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
@@ -2129,7 +2129,10 @@ class pi():
def spi_open(self, spi_channel, spi_baud, spi_flags=0):
"""
- Returns a handle for the SPI device on channel.
+ Returns a handle for the SPI device on channel. Data will be
+ transferred at baud bits per second. The flags may be used to
+ modify the default behaviour of 4-wire operation, mode 0,
+ active low chip select.
spi_channel:= 0 or 1, the SPI channel.
spi_baud:= >0, the transmission rate in bits per second.
@@ -2140,20 +2143,32 @@ class pi():
you will always run on the local Pi use the standard SPI
modules instead.
- The bottom two bits of spi_flags define the SPI mode as
- follows.
+ spiFlags consists of the least significant 8 bits.
. .
- bit bit
- 1 0
- POL PHA Mode
- 0 0 0
- 0 1 1
- 1 0 2
- 1 1 3
+ 7 6 5 4 3 2 1 0
+ n n n n W P m m
. .
- The other bits in spi_flags should be set to zero.
+ mm defines the SPI mode.
+
+ . .
+ Mode POL PHA
+ 0 0 0
+ 1 0 1
+ 2 1 0
+ 3 1 1
+ . .
+
+ P is 0 for active low chip select (normal) and 1 for active high.
+
+ W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+ nnnn defines the number of bytes (0-15) to write before switching
+ the MOSI line to MISO to read data. This field is ignored
+ if W is not set.
+
+ The other bits in flags should be set to zero.
...
# open SPI device on channel 1 in mode 3 at 20000 bits per second
@@ -2507,9 +2522,9 @@ class pi():
...
"""
status = _u2i(_pigpio_command(self._control, _PI_CMD_PROCP, script_id, 0))
- if status >= 0:
- param = struct.unpack('IIIIIIIIII', self._control.recv(40))
- return status, param
+ if status > 0:
+ params = struct.unpack('I10i', self._control.recv(44))
+ return params[0], params[1:]
return status, ()
def stop_script(self, script_id):
@@ -2975,7 +2990,33 @@ def xref():
A SPI channel.
spi_flags: 32 bit
- The flags are used to encode the SPI mode in bits 0 and 1.
+
+ spi_flags consists of the least significant 8 bits.
+
+ . .
+ 7 6 5 4 3 2 1 0
+ n n n n W P m m
+ . .
+
+ mm defines the SPI mode.
+
+ . .
+ Mode POL PHA
+ 0 0 0
+ 1 0 1
+ 2 1 0
+ 3 1 1
+ . .
+
+ P is 0 for active low chip select (normal) and 1 for active high.
+
+ W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+ nnnn defines the number of bytes (0-15) to write before switching
+ the MOSI line to MISO to read data. This field is ignored
+ if W is not set.
+
+ The other bits in flags should be set to zero.
t1:
A tick (earlier).
diff --git a/pigpiod_if.3 b/pigpiod_if.3
index 5fa5c23..d0029bd 100644
--- a/pigpiod_if.3
+++ b/pigpiod_if.3
@@ -2165,7 +2165,9 @@ PI_I2C_WRITE_FAILED.
.IP "\fBint spi_open(unsigned spi_channel, unsigned spi_baud, unsigned spi_flags)\fP"
.IP "" 4
This function returns a handle for the SPI device on channel.
-Data will be transferred at baud bits per second.
+Data will be transferred at baud bits per second. The flags may
+be used to modify the default behaviour of 4-wire operation, mode 0,
+active low chip select.
.br
@@ -2176,7 +2178,7 @@ spi_channel: 0-1.
.br
spi_baud: >1.
.br
- spi_flags: 0-3.
+ spi_flags: see below.
.br
.EE
@@ -2190,17 +2192,30 @@ PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
.br
.br
-The least significant two bits of flags define the SPI mode as follows.
+spiFlags consists of the least significant 8 bits.
.br
.br
.EX
- bit bit
+7 6 5 4 3 2 1 0
.br
- 1 0
+n n n n W P m m
.br
+
+.EE
+
+.br
+
+.br
+mm defines the SPI mode.
+
+.br
+
+.br
+
+.EX
Mode POL PHA
.br
0 0 0
@@ -2216,6 +2231,23 @@ Mode POL PHA
.br
+.br
+P is 0 for active low chip select (normal) and 1 for active high.
+
+.br
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+
+.br
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+.br
+
.br
The other bits in flags should be set to zero.
@@ -3193,8 +3225,64 @@ A SPI channel, 0 or 1.
.br
.IP "\fBspi_flags\fP" 0
-Flags which modify a SPI open command. The two least significant bits
-define the SPI mode. The other bits are undefined.
+spi_flags consists of the least significant 8 bits.
+
+.br
+
+.br
+
+.EX
+7 6 5 4 3 2 1 0
+.br
+n n n n W P m m
+.br
+
+.EE
+
+.br
+
+.br
+mm defines the SPI mode.
+
+.br
+
+.br
+
+.EX
+Mode POL PHA
+.br
+ 0 0 0
+.br
+ 1 0 1
+.br
+ 2 1 0
+.br
+ 3 1 1
+.br
+
+.EE
+
+.br
+
+.br
+P is 0 for active low chip select (normal) and 1 for active high.
+
+.br
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+
+.br
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+.br
+
+.br
+The other bits in flags should be set to zero.
.br
diff --git a/pigpiod_if.c b/pigpiod_if.c
index 4ac663e..62d852e 100644
--- a/pigpiod_if.c
+++ b/pigpiod_if.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* PIGPIOD_IF_VERSION 6 */
+/* PIGPIOD_IF_VERSION 7 */
#include
#include
@@ -777,16 +777,17 @@ int run_script(unsigned script_id, unsigned numPar, uint32_t *param)
int script_status(unsigned script_id, uint32_t *param)
{
int status;
- uint32_t p[PI_MAX_SCRIPT_PARAMS];
+ uint32_t p[PI_MAX_SCRIPT_PARAMS+1]; /* space for script status */
status = pigpio_command(gPigCommand, PI_CMD_PROCP, script_id, 0);
- if (status >= 0)
+ if (status > 0)
{
/* get the data */
- recv(gPigCommand, p, sizeof(p), MSG_WAITALL);
+ recv(gPigCommand, p, status, MSG_WAITALL);
- if (param) memcpy(param, p, sizeof(p));
+ status = p[0];
+ if (param) memcpy(param, p+1, sizeof(p)-4);
}
return status;
diff --git a/pigpiod_if.h b/pigpiod_if.h
index d99c17d..796debb 100644
--- a/pigpiod_if.h
+++ b/pigpiod_if.h
@@ -30,7 +30,7 @@ For more information, please refer to
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 6
+#define PIGPIOD_IF_VERSION 7
/*TEXT
@@ -1562,22 +1562,29 @@ D*/
int spi_open(unsigned spi_channel, unsigned spi_baud, unsigned spi_flags);
/*D
This function returns a handle for the SPI device on channel.
-Data will be transferred at baud bits per second.
+Data will be transferred at baud bits per second. The flags may
+be used to modify the default behaviour of 4-wire operation, mode 0,
+active low chip select.
. .
spi_channel: 0-1.
spi_baud: >1.
- spi_flags: 0-3.
+ spi_flags: see below.
. .
Returns a handle (>=0) if OK, otherwise PI_BAD_SPI_CHANNEL,
PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
-The least significant two bits of flags define the SPI mode as follows.
+spiFlags consists of the least significant 8 bits.
+
+. .
+7 6 5 4 3 2 1 0
+n n n n W P m m
+. .
+
+mm defines the SPI mode.
. .
- bit bit
- 1 0
Mode POL PHA
0 0 0
1 0 1
@@ -1585,6 +1592,14 @@ Mode POL PHA
3 1 1
. .
+P is 0 for active low chip select (normal) and 1 for active high.
+
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
The other bits in flags should be set to zero.
D*/
@@ -2087,8 +2102,32 @@ spi_channel::
A SPI channel, 0 or 1.
spi_flags::
-Flags which modify a SPI open command. The two least significant bits
-define the SPI mode. The other bits are undefined.
+spi_flags consists of the least significant 8 bits.
+
+. .
+7 6 5 4 3 2 1 0
+n n n n W P m m
+. .
+
+mm defines the SPI mode.
+
+. .
+Mode POL PHA
+ 0 0 0
+ 1 0 1
+ 2 1 0
+ 3 1 1
+. .
+
+P is 0 for active low chip select (normal) and 1 for active high.
+
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+The other bits in flags should be set to zero.
*str::
An array of characters.
diff --git a/pigs.1 b/pigs.1
index 4154690..d3ad8a3 100644
--- a/pigs.1
+++ b/pigs.1
@@ -2172,21 +2172,56 @@ This command returns a handle to a SPI device on channel \fBc\fP.
.br
.br
-Data will be transferred at \fBb\fP bits per second. The least
-significant two bits of the flags \fBspf\fP determine the SPI mode. All
-other bits in \fBspf\fP should be set to zero.
+Data will be transferred at \fBb\fP bits per second. The flags \fBspf\fP
+may be used to modify the default behaviour of 4-wire operation,
+mode 0, active low chip select.
+
+.br
+The flags consists of the least significant 8 bits.
.br
.EX
-Flags Mode
-0 0
-1 1
-2 2
-3 3
+7 6 5 4 3 2 1 0
+.br
+n n n n W P m m
+.br
.EE
+.br
+mm defines the SPI mode.
+
+.br
+
+.EX
+Mode POL PHA
+.br
+ 0 0 0
+.br
+ 1 0 1
+.br
+ 2 1 0
+.br
+ 3 1 1
+.br
+
+.EE
+
+.br
+P is 0 for active low chip select (normal) and 1 for active high.
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+.br
+The other bits in flags should be set to zero.
+
.br
Upon success a handle (>=0) is returned. On error a negative status code
will be returned.
@@ -3152,8 +3187,50 @@ The command expects a script id as returned by a call to \fBPROC\fP.
.br
.IP "\fBspf\fP - SPI flags (32 bits)" 0
-The command expects a flag value. The least significant two bits
-define the SPI mode.
+The flags consists of the least significant 8 bits.
+
+.br
+
+.EX
+7 6 5 4 3 2 1 0
+.br
+n n n n W P m m
+.br
+
+.EE
+
+.br
+mm defines the SPI mode.
+
+.br
+
+.EX
+Mode POL PHA
+.br
+ 0 0 0
+.br
+ 1 0 1
+.br
+ 2 1 0
+.br
+ 3 1 1
+.br
+
+.EE
+
+.br
+P is 0 for active low chip select (normal) and 1 for active high.
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+nnnn defines the number of bytes (0-15) to write before switching
+the MOSI line to MISO to read data. This field is ignored
+if W is not set.
+
+.br
+The other bits in flags should be set to zero.
.br
diff --git a/pigs.c b/pigs.c
index 7840420..23d9bfe 100644
--- a/pigs.c
+++ b/pigs.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 17+
+This version is for pigpio version 18+
*/
#include
@@ -155,15 +155,18 @@ void print_result(int sock, int rv, cmdCmd_t cmd)
break;
case 7: /* PROCP */
- printf("%d", r);
- if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
- if (r >= 0)
+ if (r != (4 + (4*PI_MAX_SCRIPT_PARAMS)))
+ {
+ printf("%d", r);
+ fatal("ERROR: %s", cmdErrStr(r));
+ }
+ else
{
p = (uint32_t *)response_buf;
-
+ printf("%d", p[0]);
for (i=0; i= 0)
- {
- recv(sock,
- response_buf,
- sizeof(uint32_t)*PI_MAX_SCRIPT_PARAMS,
- MSG_WAITALL);
- }
- break;
-
case PI_CMD_I2CPK:
case PI_CMD_I2CRD:
case PI_CMD_I2CRI:
case PI_CMD_I2CRK:
+ case PI_CMD_PROCP:
case PI_CMD_SERR:
case PI_CMD_SLR:
case PI_CMD_SPIX:
diff --git a/setup.py b/setup.py
index 34b0e30..f4021f5 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='pigpio',
- version='1.7',
+ version='1.8',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',
diff --git a/x_pigpio.py b/x_pigpio.py
index 42c139d..005206e 100755
--- a/x_pigpio.py
+++ b/x_pigpio.py
@@ -610,7 +610,7 @@ def ta():
# this test needs RXD and TXD to be connected
h = pi.serial_open("/dev/ttyAMA0", 57600)
- CHECK(10, 1, h, 0, 0, "serial open")
+ CHECK(10, 1, h>=0, 1, 0, "serial open")
(b, s) = pi.serial_read(h, 1000) # flush buffer
@@ -666,7 +666,7 @@ def tb():
# this test requires an ADXL345 on I2C bus 1 addr 0x53
h = pi.i2c_open(1, 0x53)
- CHECK(11, 1, h, 0, 0, "i2c open")
+ CHECK(11, 1, h>=0, 1, 0, "i2c open")
e = pi.i2c_write_device(h, "\x00") # move to known register
CHECK(11, 2, e, 0, 0, "i2c write device")
@@ -747,7 +747,7 @@ def tc():
# this test requires a MCP3202 on SPI channel 1
h = pi.spi_open(1, 50000)
- CHECK(12, 1, h, 0, 0, "spi open")
+ CHECK(12, 1, h>=0, 1, 0, "spi open")
(b, d) = pi.spi_xfer(h, [1,128,0])
CHECK(12, 2, b, 3, 0, "spi xfer")
diff --git a/x_pigpiod_if.c b/x_pigpiod_if.c
index 9b7ca4f..7570849 100644
--- a/x_pigpiod_if.c
+++ b/x_pigpiod_if.c
@@ -601,11 +601,11 @@ void t9()
time_sleep(0.1);
e = script_status(s, p);
if (e != PI_SCRIPT_RUNNING) break;
- if (p[9] < 1900) stop_script(s);
+ if (p[9] < 1600) stop_script(s);
}
c = t9_count - oc;
time_sleep(0.1);
- CHECK(9, 3, c, 110, 10, "run/stop script/script status");
+ CHECK(9, 3, c, 410, 10, "run/stop script/script status");
e = delete_script(s);
CHECK(9, 4, e, 0, 0, "delete script");
diff --git a/x_pigs b/x_pigs
index 9411d5d..38e35d6 100755
--- a/x_pigs
+++ b/x_pigs
@@ -86,7 +86,7 @@ s=$(pigs pfs $GPIO 800)
if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
s=$(pigs pigpv)
-if [[ $s = 17 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
+if [[ $s = 18 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
s=$(pigs prs $GPIO 255)
if [[ $s = 250 ]]; then echo "PRG-a ok"; else echo "PRG-a fail ($s)"; fi
diff --git a/x_pipe b/x_pipe
index 1ffb59e..ff28e1e 100755
--- a/x_pipe
+++ b/x_pipe
@@ -119,7 +119,7 @@ if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
echo "pigpv" >/dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s