V21
authorjoan <joan@abyz.me.uk>
Wed, 3 Sep 2014 18:52:48 +0000 (19:52 +0100)
committerjoan <joan@abyz.me.uk>
Wed, 3 Sep 2014 18:52:48 +0000 (19:52 +0100)
13 files changed:
MakeRemote
command.c
pigpio.3
pigpio.c
pigpio.h
pigpio.py
pigpiod_if.3
pigpiod_if.c
pigpiod_if.h
pigs.1
setup.py
x_pigs
x_pipe

index 96388d6d8200b82178ca63eab080723cc1a3cca2..1f96097b8892ab9feb9038d72f2327a5940b7b45 100644 (file)
@@ -23,7 +23,8 @@ install:      $(LIB)
        sudo install -m 0644 libpigpiod_if.a /usr/local/lib
        sudo install -m 0755 -d              /usr/local/bin
        sudo install -m 0755 pigs            /usr/local/bin
-       sudo python setup.py install
+       sudo python2 setup.py install
+       sudo python3 setup.py install
        sudo install -m 0755 -d              /usr/local/man/man1
        sudo install -m 0644 *.1             /usr/local/man/man1
        sudo install -m 0755 -d              /usr/local/man/man3
index 36f8f9e7a4586bef90254d47d56ebc0dff225ba9..23f372bd5c2d59dc9bf234d891bbf5d578420e04 100644 (file)
--- a/command.c
+++ b/command.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 21+
 */
 
 #include <stdio.h>
@@ -454,6 +454,9 @@ static errInfo_t errInfo[]=
    {PI_SER_READ_FAILED  , "ser read failed"},
    {PI_SER_READ_NO_DATA , "ser read no data available"},
    {PI_UNKNOWN_COMMAND  , "unknown command"},
+   {PI_SPI_XFER_FAILED  , "spi xfer/read/write failed"},
+   {PI_BAD_POINTER      , "bad (NULL) pointer"},
+   {PI_NO_AUX_SPI       , "need a B+ for auxiliary SPI"},
 
 };
 
index 7089390fcc1fcdfa32329c95d663eafaa5929ea5..824c3e2fcf384e11b738082cde3f897c7f376b3e 100644 (file)
--- a/pigpio.3
+++ b/pigpio.3
@@ -2370,6 +2370,13 @@ active low chip select.
 
 .br
 
+.br
+An auxiliary SPI device is available on the B+ and may be
+selected by setting the A bit in the flags.  The auxiliary
+device has 3 chip selects and a selectable word size in bits.
+
+.br
+
 .br
 
 .EX
@@ -2377,7 +2384,7 @@ active low chip select.
 .br
  spiBaud: >1
 .br
-spiFlags: 0-0xFF
+spiFlags: see below
 .br
 
 .EE
@@ -2386,21 +2393,21 @@ spiFlags: 0-0xFF
 
 .br
 Returns a handle (>=0) if OK, otherwise PI_BAD_SPI_CHANNEL,
-PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
+PI_BAD_SPI_SPEED, PI_BAD_FLAGS, PI_NO_AUX_SPI, or PI_SPI_OPEN_FAILED.
 
 .br
 
 .br
-spiFlags consists of the least significant 8 bits.
+spiFlags consists of the least significant 22 bits.
 
 .br
 
 .br
 
 .EX
-7 6 5 4 3 2 1 0
+21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
 .br
-n n n n W P m m
+ b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
 .br
 
 .EE
@@ -2431,19 +2438,51 @@ Mode POL PHA
 .br
 
 .br
-P is 0 for active low chip select (normal) and 1 for active high.
+px is 0 if CEx is active low (default) and 1 for active high.
+
+.br
+
+.br
+ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise.
+
+.br
+
+.br
+A is 0 for the standard SPI device, 1 for the auxiliary SPI.  The
+auxiliary device is only present on the B+.
 
 .br
 
 .br
-W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.  Standard
+SPI device only.
 
 .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.
+if W is not set.  Standard SPI device only.
+
+.br
+
+.br
+T is 1 if the least significant bit is transmitted on MOSI first, the
+default (0) shifts the most significant bit out first.  Auxiliary SPI
+device only.
+
+.br
+
+.br
+R is 1 if the least significant bit is received on MISO first, the
+default (0) receives the most significant bit first.  Auxiliary SPI
+device only.
+
+.br
+
+.br
+bbbbbb defines the word size in bits (0-32).  The default (0)
+sets 8 bits per word.  Auxiliary SPI device only.
 
 .br
 
@@ -3611,7 +3650,7 @@ Returns the actual length of the delay in microseconds.
 .br
 
 .br
-Delays of 50 microseconds or less use busy waits.
+Delays of 100 microseconds or less use busy waits.
 
 .IP "\fBuint32_t gpioTick(void)\fP"
 .IP "" 4
@@ -4728,6 +4767,26 @@ typedef struct
 
 .br
 
+.IP "\fBgpioSample_t\fP" 0
+
+.EX
+typedef struct
+.br
+{
+.br
+   uint32_t tick;
+.br
+   uint32_t level;
+.br
+} gpioSample_t;
+.br
+
+.EE
+
+.br
+
+.br
+
 .IP "\fBgpioSignalFunc_t\fP" 0
 
 .EX
@@ -5195,7 +5254,7 @@ PI_PUD_UP 2
 .br
 
 .br
-An array of pulsed to be added to a waveform.
+An array of pulses to be added to a waveform.
 
 .br
 
@@ -5519,64 +5578,7 @@ A SPI channel, 0 or 1.
 .br
 
 .br
-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.
+See \fBspiOpen\fP.
 
 .br
 
@@ -6174,6 +6176,8 @@ A 16-bit word value.
 .br
 #define PI_BAD_POINTER      -90 // bad (NULL) pointer
 .br
+#define PI_NO_AUX_SPI       -91 // need a B+ for auxiliary SPI
+.br
 
 .br
 
index 8ddab172f7402dd141d8b11b34924783950c368a..ec1f3d61063fd589839458f903b3ffed7797b509 100644 (file)
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 For more information, please refer to <http://unlicense.org/>
 */
 
-/* pigpio version 20 */
+/* pigpio version 21 */
 
 #include <stdio.h>
 #include <string.h>
@@ -286,6 +286,7 @@ 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
@@ -294,9 +295,8 @@ bit 0 READ_LAST_NOT_SET_ERROR
 #define PWM_BASE   0x2020C000
 #define SPI_BASE   0x20204000
 #define SYST_BASE  0x20003000
-#define UART0_BASE 0x20201000
-#define UART1_BASE 0x20215000
 
+#define AUX_LEN   0xD8
 #define CLK_LEN   0xA8
 #define DMA_LEN   0x1000 /* allow access to all channels */
 #define GPIO_LEN  0xB4
@@ -491,23 +491,21 @@ bit 0 READ_LAST_NOT_SET_ERROR
 #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_LEN_LONG    (1<<25)
+#define SPI_CS_DMA_LEN     (1<<24)
+#define SPI_CS_CSPOLS(x) ((x)<<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)
@@ -527,7 +525,7 @@ bit 0 READ_LAST_NOT_SET_ERROR
 #define SPI_CS1     1
 #define SPI_CS2     2
 
-/* SPI gpios. */
+/* standard SPI gpios (ALT0) */
 
 #define PI_SPI_CE0   8
 #define PI_SPI_CE1   7
@@ -535,6 +533,80 @@ bit 0 READ_LAST_NOT_SET_ERROR
 #define PI_SPI_MISO  9
 #define PI_SPI_MOSI 10
 
+/* auxiliary SPI gpios (ALT4) */
+
+#define PI_ASPI_CE0  18
+#define PI_ASPI_CE1  17
+#define PI_ASPI_CE2  16
+#define PI_ASPI_MISO 19
+#define PI_ASPI_MOSI 20
+#define PI_ASPI_SCLK 21
+
+/* AUX */
+
+#define AUX_IRQ     0
+#define AUX_ENABLES 1
+
+#define AUX_MU_IO_REG   16
+#define AUX_MU_IER_REG  17
+#define AUX_MU_IIR_REG  18
+#define AUX_MU_LCR_REG  19
+#define AUX_MU_MCR_REG  20
+#define AUX_MU_LSR_REG  21
+#define AUX_MU_MSR_REG  22
+#define AUX_MU_SCRATCH  23
+#define AUX_MU_CNTL_REG 24
+#define AUX_MU_STAT_REG 25
+#define AUX_MU_BAUD_REG 26
+
+#define AUX_SPI0_CNTL0_REG 32
+#define AUX_SPI0_CNTL1_REG 33
+#define AUX_SPI0_STAT_REG  34
+#define AUX_SPI0_PEEK_REG  35
+
+#define AUX_SPI0_IO_REG    40
+#define AUX_SPI0_TX_HOLD   44
+
+#define AUX_SPI1_CNTL0_REG 48
+#define AUX_SPI1_CNTL1_REG 49
+#define AUX_SPI1_STAT_REG  50
+#define AUX_SPI1_PEEK_REG  51
+
+#define AUX_SPI1_IO_REG    56
+#define AUX_SPI1_TX_HOLD   60
+
+#define AUXENB_SPI2 (1<<2)
+#define AUXENB_SPI1 (1<<1)
+#define AUXENB_UART (1<<0)
+
+#define AUXSPI_CNTL0_SPEED(x)      ((x)<<20)
+#define AUXSPI_CNTL0_CS(x)         ((x)<<17)
+#define AUXSPI_CNTL0_POSTINP         (1<<16)
+#define AUXSPI_CNTL0_VAR_CS          (1<<15)
+#define AUXSPI_CNTL0_VAR_WIDTH       (1<<14)
+#define AUXSPI_CNTL0_DOUT_HOLD(x)  ((x)<<12)
+#define AUXSPI_CNTL0_ENABLE          (1<<11)
+#define AUXSPI_CNTL0_IN_RISING(x)  ((x)<<10)
+#define AUXSPI_CNTL0_CLR_FIFOS       (1<<9)
+#define AUXSPI_CNTL0_OUT_RISING(x) ((x)<<8)
+#define AUXSPI_CNTL0_INVERT_CLK(x) ((x)<<7)
+#define AUXSPI_CNTL0_MSB_FIRST(x)  ((x)<<6)
+#define AUXSPI_CNTL0_SHIFT_LEN(x)  ((x)<<0)
+
+#define AUXSPI_CNTL1_CS_HIGH(x)  ((x)<<8)
+#define AUXSPI_CNTL1_TX_IRQ        (1<<7)
+#define AUXSPI_CNTL1_DONE_IRQ      (1<<6)
+#define AUXSPI_CNTL1_MSB_FIRST(x)((x)<<1)
+#define AUXSPI_CNTL1_KEEP_INPUT    (1<<0)
+
+#define AUXSPI_STAT_TX_FIFO(x) ((x)<<28)
+#define AUXSPI_STAT_RX_FIFO(x) ((x)<<20)
+#define AUXSPI_STAT_TX_FULL      (1<<10)
+#define AUXSPI_STAT_TX_EMPTY     (1<<9)
+#define AUXSPI_STAT_RX_EMPTY     (1<<7)
+#define AUXSPI_STAT_BUSY         (1<<6)
+#define AUXSPI_STAT_BITS(x)    ((x)<<0)
+
 /* --------------------------------------------------------------- */
 
 #define NORMAL_DMA (DMA_NO_WIDE_BURSTS | DMA_WAIT_RESP)
@@ -781,6 +853,19 @@ typedef struct
    uint32_t flags;
 } spiInfo_t;
 
+#define PI_SPI_FLAGS_CHANNEL(x)    ((x&7)<<29)
+
+#define PI_SPI_FLAGS_GET_CHANNEL(x) (((x)>>29)&7)
+#define PI_SPI_FLAGS_GET_BITLEN(x)  (((x)>>16)&63)
+#define PI_SPI_FLAGS_GET_RX_LSB(x)  (((x)>>15)&1)
+#define PI_SPI_FLAGS_GET_TX_LSB(x)  (((x)>>14)&1)
+#define PI_SPI_FLAGS_GET_3WREN(x)   (((x)>>10)&15)
+#define PI_SPI_FLAGS_GET_3WIRE(x)   (((x)>>9)&1)
+#define PI_SPI_FLAGS_GET_AUX_SPI(x) (((x)>>8)&1)
+#define PI_SPI_FLAGS_GET_RESVD(x)   (((x)>>5)&7)
+#define PI_SPI_FLAGS_GET_CSPOLS(x)  (((x)>>2)&7)
+#define PI_SPI_FLAGS_GET_MODE(x)     ((x)&3)
+
 typedef struct
 {
    uint32_t startTick;
@@ -982,16 +1067,17 @@ static dmaIPage_t * * dmaIPhys = MAP_FAILED;
 static dmaOPage_t * * dmaOVirt = MAP_FAILED;
 static dmaOPage_t * * dmaOPhys = MAP_FAILED;
 
-static volatile uint32_t  * clkReg  = MAP_FAILED;
-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 * auxReg  = MAP_FAILED;
+static volatile uint32_t * clkReg  = MAP_FAILED;
+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;
-static volatile uint32_t  * dmaOut  = MAP_FAILED;
+static volatile uint32_t * dmaIn   = MAP_FAILED;
+static volatile uint32_t * dmaOut  = MAP_FAILED;
 
 /* constant data */
 
@@ -2852,6 +2938,10 @@ int i2cClose(unsigned handle)
 
 /* ======================================================================= */
 
+/*SPI */
+
+static uint32_t spi_dummy; /* only used to prevent warning */
+
 static unsigned old_mode_ce0;
 static unsigned old_mode_ce1;
 static unsigned old_mode_sclk;
@@ -2861,52 +2951,223 @@ 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 unsigned old_mode_ace0;
+static unsigned old_mode_ace1;
+static unsigned old_mode_ace2;
+static unsigned old_mode_asclk;
+static unsigned old_mode_amiso;
+static unsigned old_mode_amosi;
 
-static void spiInit(void)
+static uint32_t old_spi_cntl0;
+static uint32_t old_spi_cntl1;
+
+static void spiInit(uint32_t flags)
 {
-   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);
+   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_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);
+      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];
 
-   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);
+   }
 }
 
-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);
+void spiTerm(uint32_t flags)
+{
+   int resvd;
 
-   spiReg[SPI_CS]  = old_spi_cs;
-   spiReg[SPI_CLK] = old_spi_clk;
+   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;
+   }
 }
 
-#define PI_SPI_FLAGS_CHAN(x)  ((x)<<30)
+uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf)
+{
+   uint32_t bits=0;
 
-/*
-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(
+   if (buf)
+   {
+      if      (bitlen <=  8) bits = *((( uint8_t*)buf)+pos);
+      else if (bitlen <= 16) bits = *(((uint16_t*)buf)+pos);
+      else                   bits = *(((uint32_t*)buf)+pos);
+
+      if (msbf) bits <<= (32-bitlen);
+   }
+
+   return bits;
+}
+
+void _spiRXBits(char *buf, int pos, int bitlen, int msbf, uint32_t bits)
+{
+   if (buf)
+   {
+      if (!msbf) bits >>= (32-bitlen);
+
+      if      (bitlen <=  8) *((( uint8_t*)buf)+pos) = bits;
+      else if (bitlen <= 16) *(((uint16_t*)buf)+pos) = bits;
+      else                   *(((uint32_t*)buf)+pos) = bits;
+   }
+}
+
+
+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 mode, bitlen, txmsbf, rxmsbf, channel;
+   unsigned txCnt=0;
+   unsigned rxCnt=0;
+   uint32_t spiDefaults;
+   uint32_t statusReg;
+   int txFull, rxEmpty;
+
+   channel = PI_SPI_FLAGS_GET_CHANNEL(flags);
+   mode   =  PI_SPI_FLAGS_GET_MODE   (flags);
+   bitlen =  PI_SPI_FLAGS_GET_BITLEN (flags);
+   if (!bitlen) bitlen = 8;
+   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;
+
+   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;
+
+   auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE | spiDefaults;
+   auxReg[AUX_SPI0_CNTL1_REG] = AUXSPI_CNTL1_MSB_FIRST(rxmsbf);
+
+   while ((txCnt < count) || (rxCnt < count))
+   {
+      statusReg = auxReg[AUX_SPI0_STAT_REG];
+
+      rxEmpty = statusReg & AUXSPI_STAT_RX_EMPTY;
+
+      txFull = (((statusReg>>28)&15) > 2);
+
+      if (rxCnt < count)
+      {
+         if (!rxEmpty)
+         {
+            _spiRXBits(rxBuf, rxCnt++, bitlen, rxmsbf, auxReg[AUX_SPI0_IO_REG]);
+         }
+      }
+
+      if (txCnt < count)
+      {
+         if (!txFull)
+         {
+            if (txCnt != (count-1))
+            {
+               auxReg[AUX_SPI0_TX_HOLD] =
+                  _spiTXBits(txBuf, txCnt++, bitlen, txmsbf);
+            }
+            else
+            {
+               auxReg[AUX_SPI0_IO_REG] =
+                  _spiTXBits(txBuf, txCnt++, bitlen, txmsbf);
+            }
+         }
+      }
+   }
+
+   while ((auxReg[AUX_SPI0_STAT_REG] & AUXSPI_STAT_BUSY)) ;
+
+   auxReg[AUX_SPI0_CNTL0_REG] = spiDefaults; /* stop */
+}
+
+static void spiGoS(
    unsigned speed,
    uint32_t flags,
    char     *txBuf,
@@ -2917,17 +3178,20 @@ static void spiGo(
    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) |
+   unsigned mode, channel, cspol, cspols, flag3w, ren3w;
+   uint32_t status;
+
+   channel = PI_SPI_FLAGS_GET_CHANNEL(flags);
+   mode   =  PI_SPI_FLAGS_GET_MODE   (flags);
+   cspols =  PI_SPI_FLAGS_GET_CSPOLS(flags);
+   cspol  =  (cspols>>channel) & 1;
+   flag3w =  PI_SPI_FLAGS_GET_3WIRE(flags);
+   ren3w =   PI_SPI_FLAGS_GET_3WREN(flags);
+
+   spiDefaults = SPI_CS_MODE(mode)     |
+                 SPI_CS_CSPOLS(cspols) |
+                 SPI_CS_CS(channel)    |
+                 SPI_CS_CSPOL(cspol)   |
                  SPI_CS_CLEAR(3);
 
    if (flag3w)
@@ -2957,19 +3221,21 @@ static void spiGo(
 
    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++;
-      }
+      status = spiReg[SPI_CS];
 
-      while((rxCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_RXD)))
+      while((rxCnt < cnt) && ((status & SPI_CS_RXD)))
       {
          if (rxBuf) rxBuf[rxCnt] = spiReg[SPI_FIFO];
          else       spi_dummy    = spiReg[SPI_FIFO];
          rxCnt++;
       }
+
+      while((txCnt < cnt) && ((status & SPI_CS_TXD)))
+      {
+         if (txBuf) spiReg[SPI_FIFO] = txBuf[txCnt];
+         else       spiReg[SPI_FIFO] = 0;
+         txCnt++;
+      }
    }
 
    while (!(spiReg[SPI_CS] & SPI_CS_DONE)) ;
@@ -2978,23 +3244,25 @@ static void spiGo(
 
    cnt += cnt3w;
 
+   spiReg[SPI_CS] |= SPI_CS_REN;
+
    while((txCnt < cnt) || (rxCnt < cnt))
    {
-      spiReg[SPI_CS] |= SPI_CS_REN;
+      status = spiReg[SPI_CS];
 
-      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)))
+      while((rxCnt < cnt) && ((status & SPI_CS_RXD)))
       {
          if (rxBuf) rxBuf[rxCnt] = spiReg[SPI_FIFO];
          else       spi_dummy    = spiReg[SPI_FIFO];
          rxCnt++;
       }
+
+      while((txCnt < cnt) && ((status & SPI_CS_TXD)))
+      {
+         if (txBuf) spiReg[SPI_FIFO] = txBuf[txCnt];
+         else       spiReg[SPI_FIFO] = 0;
+         txCnt++;
+      }
    }
 
    while (!(spiReg[SPI_CS] & SPI_CS_DONE)) ;
@@ -3002,13 +3270,30 @@ static void spiGo(
    spiReg[SPI_CS] = spiDefaults; /* stop */
 }
 
-static int spiAnyOpen(void)
+static void spiGo(
+   unsigned speed,
+   uint32_t flags,
+   char     *txBuf,
+   char     *rxBuf,
+   unsigned count)
 {
-   int i;
+   if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
+      spiGoA(speed, flags, txBuf, rxBuf, count);
+   else
+      spiGoS(speed, flags, txBuf, rxBuf, count);
+}
+
+static int spiAnyOpen(uint32_t flags)
+{
+   int i, aux;
+
+   aux = PI_SPI_FLAGS_GET_AUX_SPI(flags);
 
    for (i=0; i<PI_SPI_SLOTS; i++)
    {
-      if (spiInfo[i].state == PI_SPI_OPENED) return 1;
+      if ((spiInfo[i].state == PI_SPI_OPENED) &&
+         (PI_SPI_FLAGS_GET_AUX_SPI(spiInfo[i].flags) == aux))
+            return 1;
    }
    return 0;
 }
@@ -3022,16 +3307,26 @@ int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)
 
    CHECK_INITED;
 
-   if (spiChan >= PI_NUM_SPI_CHANNEL)
+   if (PI_SPI_FLAGS_GET_AUX_SPI(spiFlags))
+   {
+      if (gpioHardwareRevision() < 16)
+         SOFT_ERROR(PI_NO_AUX_SPI, "no auxiliary SPI, need a B+");
+
+      i = PI_NUM_AUX_SPI_CHANNEL;
+   }
+   else
+      i = PI_NUM_STD_SPI_CHANNEL;
+
+   if (spiChan >= i)
       SOFT_ERROR(PI_BAD_SPI_CHANNEL, "bad spiChan (%d)", spiChan);
 
-   if (!spiBaud)
+   if ((spiBaud < MIN_SPI_SPEED) || (spiBaud > MAX_SPI_SPEED))
       SOFT_ERROR(PI_BAD_SPI_SPEED, "bad spiBaud (%d)", spiBaud);
 
-   if (spiFlags > 256)
+   if (spiFlags > (1<<22))
       SOFT_ERROR(PI_BAD_FLAGS, "bad spiFlags (0x%X)", spiFlags);
 
-   if (!spiAnyOpen()) spiInit(); /* initialise on first open */
+   if (!spiAnyOpen(spiFlags)) spiInit(spiFlags); /* initialise on first open */
 
    slot = -1;
 
@@ -3049,7 +3344,7 @@ int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)
       SOFT_ERROR(PI_NO_HANDLE, "no SPI handles");
 
    spiInfo[slot].speed = spiBaud;
-   spiInfo[slot].flags = spiFlags | PI_SPI_FLAGS_CHAN(spiChan);
+   spiInfo[slot].flags = spiFlags | PI_SPI_FLAGS_CHANNEL(spiChan);
 
    return slot;
 }
@@ -3068,7 +3363,8 @@ int spiClose(unsigned handle)
 
    spiInfo[handle].state = PI_I2C_CLOSED;
 
-   if (!spiAnyOpen()) spiTerm(); /* terminate on last close */
+   if (!spiAnyOpen(spiInfo[handle].flags))
+      spiTerm(spiInfo[handle].flags); /* terminate on last close */
 
    return 0;
 }
@@ -4979,6 +5275,11 @@ static int initPeripherals(void)
    if (pcmReg == MAP_FAILED)
       SOFT_ERROR(PI_INIT_FAILED, "mmap pcm failed (%m)");
 
+   auxReg  = initMapMem(fdMem, AUX_BASE,  AUX_LEN);
+
+   if (auxReg == MAP_FAILED)
+      SOFT_ERROR(PI_INIT_FAILED, "mmap aux failed (%m)");
+
    return 0;
 }
 
@@ -5120,9 +5421,10 @@ static int initDMAcbs(void)
    DBG(DBG_STARTUP, "dmaBloc=%08X dmaIn=%08X",
       (uint32_t)dmaBloc, (uint32_t)dmaIn);
 
-   DBG(DBG_STARTUP, "gpioReg=%08X pwmReg=%08X pcmReg=%08X clkReg=%08X",
+   DBG(DBG_STARTUP,
+      "gpioReg=%08X pwmReg=%08X pcmReg=%08X clkReg=%08X auxReg=%08X",
       (uint32_t)gpioReg, (uint32_t)pwmReg,
-      (uint32_t)pcmReg,  (uint32_t)clkReg); 
+      (uint32_t)pcmReg,  (uint32_t)clkReg, (uint32_t)auxReg); 
 
    for (i=0; i<DMAI_PAGES; i++)
       DBG(DBG_STARTUP, "dmaIPhys[%d]=%08X", i, (uint32_t)dmaIPhys[i]);
@@ -5431,6 +5733,7 @@ static void initClearGlobals(void)
    dmaVirt = MAP_FAILED;
    dmaPhys = MAP_FAILED;
 
+   auxReg  = MAP_FAILED;
    clkReg  = MAP_FAILED;
    dmaReg  = MAP_FAILED;
    gpioReg = MAP_FAILED;
@@ -5485,6 +5788,7 @@ static void initReleaseResources(void)
 
    /* release mmap'd memory */
 
+   if (auxReg  != MAP_FAILED) munmap((void *)auxReg,  AUX_LEN);
    if (clkReg  != MAP_FAILED) munmap((void *)clkReg,  CLK_LEN);
    if (dmaReg  != MAP_FAILED) munmap((void *)dmaReg,  DMA_LEN);
    if (gpioReg != MAP_FAILED) munmap((void *)gpioReg, GPIO_LEN);
@@ -5493,6 +5797,7 @@ static void initReleaseResources(void)
    if (systReg != MAP_FAILED) munmap((void *)systReg, SYST_LEN);
    if (spiReg  != MAP_FAILED) munmap((void *)spiReg,  SPI_LEN);
 
+   auxReg  = MAP_FAILED;
    clkReg  = MAP_FAILED;
    dmaReg  = MAP_FAILED;
    gpioReg = MAP_FAILED;
index e15e85fd3b769e4cac8c40a07363ebe37bfb1eb4..6d134618b0f561d330b2e39a6782879d6bfc94d0 100644 (file)
--- a/pigpio.h
+++ b/pigpio.h
@@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
 #include <stdint.h>
 #include <pthread.h>
 
-#define PIGPIO_VERSION 20
+#define PIGPIO_VERSION 21
 
 /*TEXT
 
@@ -483,20 +483,30 @@ typedef void *(gpioThreadFunc_t) (void *);
 
 /* I2C, SPI, SER */
 
+#define MIN_SPI_SPEED 32000
+#define MAX_SPI_SPEED 125000000
+
 #define PI_I2C_SLOTS 32
-#define PI_SPI_SLOTS 8
+#define PI_SPI_SLOTS 16
 #define PI_SER_SLOTS 8
 
 #define PI_NUM_I2C_BUS 2
-#define PI_NUM_SPI_CHANNEL 2
+
+#define PI_NUM_AUX_SPI_CHANNEL 3
+#define PI_NUM_STD_SPI_CHANNEL 2
 
 #define PI_MAX_I2C_DEVICE_COUNT 8192
 #define PI_MAX_SPI_DEVICE_COUNT 8192
 
-#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)
+#define PI_SPI_FLAGS_BITLEN(x) ((x&63)<<16)
+#define PI_SPI_FLAGS_RX_LSB(x)  ((x&1)<<15)
+#define PI_SPI_FLAGS_TX_LSB(x)  ((x&1)<<14)
+#define PI_SPI_FLAGS_3WREN(x)  ((x&15)<<10)
+#define PI_SPI_FLAGS_3WIRE(x)   ((x&1)<<9)
+#define PI_SPI_FLAGS_AUX_SPI(x) ((x&1)<<8)
+#define PI_SPI_FLAGS_RESVD(x)   ((x&7)<<5)
+#define PI_SPI_FLAGS_CSPOLS(x)  ((x&7)<<2)
+#define PI_SPI_FLAGS_MODE(x)    ((x&3))
 
 /* Longest busy delay */
 
@@ -1886,20 +1896,24 @@ 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.
 
+An auxiliary SPI device is available on the B+ and may be
+selected by setting the A bit in the flags.  The auxiliary
+device has 3 chip selects and a selectable word size in bits.
+
 . .
  spiChan: 0-1
  spiBaud: >1
-spiFlags: 0-0xFF
+spiFlags: 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.
+PI_BAD_SPI_SPEED, PI_BAD_FLAGS, PI_NO_AUX_SPI, or PI_SPI_OPEN_FAILED.
 
-spiFlags consists of the least significant 8 bits.
+spiFlags consists of the least significant 22 bits.
 
 . .
-7 6 5 4 3 2 1 0
-n n n n W P m m
+21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+ b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
 . .
 
 mm defines the SPI mode.
@@ -1912,13 +1926,30 @@ Mode POL PHA
  3    1   1
 . .
 
-P is 0 for active low chip select (normal) and 1 for active high.
+px is 0 if CEx is active low (default) and 1 for active high.
+
+ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise.
+
+A is 0 for the standard SPI device, 1 for the auxiliary SPI.  The
+auxiliary device is only present on the B+.
 
-W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.  Standard
+SPI device only.
 
 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.
+if W is not set.  Standard SPI device only.
+
+T is 1 if the least significant bit is transmitted on MOSI first, the
+default (0) shifts the most significant bit out first.  Auxiliary SPI
+device only.
+
+R is 1 if the least significant bit is received on MISO first, the
+default (0) receives the most significant bit first.  Auxiliary SPI
+device only.
+
+bbbbbb defines the word size in bits (0-32).  The default (0)
+sets 8 bits per word.  Auxiliary SPI device only.
 
 The other bits in flags should be set to zero.
 D*/
@@ -2614,7 +2645,7 @@ micros: the number of microseconds to sleep
 
 Returns the actual length of the delay in microseconds.
 
-Delays of 50 microseconds or less use busy waits.
+Delays of 100 microseconds or less use busy waits.
 D*/
 
 
@@ -3230,6 +3261,15 @@ typedef struct
 } gpioPulse_t;
 . .
 
+gpioSample_t::
+. .
+typedef struct
+{
+   uint32_t tick;
+   uint32_t level;
+} gpioSample_t;
+. .
+
 gpioSignalFunc_t::
 . .
 typedef void (*gpioSignalFunc_t) (int signum);
@@ -3415,7 +3455,7 @@ pulseLen::
 
 *pulses::
 
-An array of pulsed to be added to a waveform.
+An array of pulses to be added to a waveform.
 
 pulsewidth::0, 500-2500
 . .
@@ -3546,32 +3586,7 @@ A SPI channel, 0 or 1.
 
 spiFlags::
 
-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.
+See [*spiOpen*].
 
 spiSS::
 
@@ -3903,6 +3918,7 @@ after this command is issued.
 #define PI_UNKNOWN_COMMAND  -88 // unknown command
 #define PI_SPI_XFER_FAILED  -89 // spi xfer/read/write failed
 #define PI_BAD_POINTER      -90 // bad (NULL) pointer
+#define PI_NO_AUX_SPI       -91 // need a B+ for auxiliary SPI
 
 /*DEF_E*/
 
index ab176739794c0c017f4b24df249308bad56982e5..4fb947eef62909c67f189d080a7a6f95df513c8f 100644 (file)
--- a/pigpio.py
+++ b/pigpio.py
@@ -246,7 +246,7 @@ import os
 import atexit
 import codecs
 
-VERSION = "1.10"
+VERSION = "1.11"
 
 exceptions = True
 
@@ -485,6 +485,8 @@ PI_SER_READ_FAILED  =-86
 PI_SER_READ_NO_DATA =-87
 PI_UNKNOWN_COMMAND  =-88
 PI_SPI_XFER_FAILED  =-89
+_PI_BAD_POINTER     =-90
+PI_NO_AUX_SPI       =-91
 
 # pigpio error text
 
@@ -576,6 +578,8 @@ _errors=[
    [PI_SER_READ_NO_DATA  , "ser read no data available"],
    [PI_UNKNOWN_COMMAND   , "unknown command"],
    [PI_SPI_XFER_FAILED   , "SPI xfer/read/write failed"],
+   [_PI_BAD_POINTER      , "bad (NULL) pointer"],
+   [PI_NO_AUX_SPI        , "need a B+ for auxiliary SPI"],
 ]
 
 class _socklock:
@@ -1745,7 +1749,7 @@ class pi():
       Normally you would only use the [*i2c_**] functions if
       you are or will be connecting to the Pi over a network.  If
       you will always run on the local Pi use the standard smbus
-      modules instead.
+      module instead.
 
       ...
       h = pi.i2c_open(1, 0x53) # open device at address 0x53 on bus 1
@@ -2100,7 +2104,7 @@ class pi():
 
       # Don't raise exception.  Must release lock.
       bytes = u2i(_pigpio_command_ext(
-         self.sl, _PI_CMD_I2CPK, handle, reg, len(data), [data]), False)
+         self.sl, _PI_CMD_I2CPK, handle, reg, len(data), [data], False))
       if bytes > 0:
          data = self._rxbuf(bytes)
       else:
@@ -2169,7 +2173,7 @@ class pi():
 
       # Don't raise exception.  Must release lock.
       bytes = u2i(_pigpio_command_ext(
-         self.sl, _PI_CMD_I2CRI, handle, reg, 4, extents), False)
+         self.sl, _PI_CMD_I2CRI, handle, reg, 4, extents, False))
       if bytes > 0:
          data = self._rxbuf(bytes)
       else:
@@ -2184,6 +2188,11 @@ class pi():
       modify the default behaviour of 4-wire operation, mode 0,
       active low chip select.
 
+      An auxiliary SPI device is available on the B+ and may be
+      selected by setting the A bit in the flags.  The auxiliary
+      device has 3 chip selects and a selectable word size in bits.
+
+
       spi_channel:= 0 or 1, the SPI channel.
          spi_baud:= >0, the transmission rate in bits per second.
         spi_flags:= see below.
@@ -2191,32 +2200,50 @@ class pi():
       Normally you would only use the [*spi_**] functions if
       you are or will be connecting to the Pi over a network.  If
       you will always run on the local Pi use the standard SPI
-      modules instead.
+      module instead.
 
-      spiFlags consists of the least significant 8 bits.
+      spi_flags consists of the least significant 22 bits.
 
       . .
-      7 6 5 4 3 2 1 0
-      n n n n W P m m
+      21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+       b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
       . .
 
       mm defines the SPI mode.
 
       . .
       Mode POL PHA
-      0    0   0
-      1    0   1
-      2    1   0
-      3    1   1
+       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.
+      px is 0 if CEx is active low (default) and 1 for active high.
+
+      ux is 0 if the CEx gpio is reserved for SPI (default)
+      and 1 otherwise.
+
+      A is 0 for the standard SPI device, 1 for the auxiliary SPI.
+      The auxiliary device is only present on the B+.
 
       W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+      Standard SPI device only.
 
-      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.
+      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.  Standard SPI device only.
+
+      T is 1 if the least significant bit is transmitted on MOSI
+      first, the default (0) shifts the most significant bit out
+      first.  Auxiliary SPI device only.
+
+      R is 1 if the least significant bit is received on MISO
+      first, the default (0) receives the most significant bit
+      first.  Auxiliary SPI device only.
+
+      bbbbbb defines the word size in bits (0-32).  The default (0)
+      sets 8 bits per word.  Auxiliary SPI device only.
 
       The other bits in flags should be set to zero.
 
@@ -2333,7 +2360,7 @@ class pi():
 
       # Don't raise exception.  Must release lock.
       bytes = u2i(_pigpio_command_ext(
-         self.sl, _PI_CMD_SPIX, handle, 0, len(data), [data]), False)
+         self.sl, _PI_CMD_SPIX, handle, 0, len(data), [data], False))
       if bytes > 0:
          data = self._rxbuf(bytes)
       else:
@@ -2353,7 +2380,7 @@ class pi():
       Normally you would only use the [*serial_**] functions if
       you are or will be connecting to the Pi over a network.  If
       you will always run on the local Pi use the standard serial
-      modules instead.
+      module instead.
 
       ...
       h1 = pi.serial_open("/dev/ttyAMA0", 300)
@@ -3066,33 +3093,7 @@ def xref():
    A SPI channel.
 
    spi_flags: 32 bit
-
-   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.
+   See [*spi_open*].
 
    t1:
    A tick (earlier).
index 10f86440bab5d16f93cf820e6b4074c22bf1b012..ea4346c13f6f5ce719f76319e3c693d6fed33e0a 100644 (file)
@@ -2228,6 +2228,13 @@ active low chip select.
 
 .br
 
+.br
+An auxiliary SPI device is available on the B+ and may be
+selected by setting the A bit in the flags.  The auxiliary
+device has 3 chip selects and a selectable word size in bits.
+
+.br
+
 .br
 
 .EX
@@ -2244,21 +2251,21 @@ spi_channel: 0-1.
 
 .br
 Returns a handle (>=0) if OK, otherwise PI_BAD_SPI_CHANNEL,
-PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
+PI_BAD_SPI_SPEED, PI_BAD_FLAGS, PI_NO_AUX_SPI, or PI_SPI_OPEN_FAILED.
 
 .br
 
 .br
-spiFlags consists of the least significant 8 bits.
+spi_flags consists of the least significant 22 bits.
 
 .br
 
 .br
 
 .EX
-7 6 5 4 3 2 1 0
+21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
 .br
-n n n n W P m m
+ b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
 .br
 
 .EE
@@ -2289,19 +2296,51 @@ Mode POL PHA
 .br
 
 .br
-P is 0 for active low chip select (normal) and 1 for active high.
+px is 0 if CEx is active low (default) and 1 for active high.
+
+.br
+
+.br
+ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise.
+
+.br
 
 .br
+A is 0 for the standard SPI device, 1 for the auxiliary SPI.  The
+auxiliary device is only present on the B+.
 
 .br
-W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.  Standard
+SPI device only.
 
 .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.
+if W is not set.  Standard SPI device only.
+
+.br
+
+.br
+T is 1 if the least significant bit is transmitted on MOSI first, the
+default (0) shifts the most significant bit out first.  Auxiliary SPI
+device only.
+
+.br
+
+.br
+R is 1 if the least significant bit is received on MISO first, the
+default (0) receives the most significant bit first.  Auxiliary SPI
+device only.
+
+.br
+
+.br
+bbbbbb defines the word size in bits (0-32).  The default (0)
+sets 8 bits per word.  Auxiliary SPI device only.
 
 .br
 
@@ -3156,7 +3195,7 @@ PI_PUD_UP 2
 .br
 
 .IP "\fB*pulses\fP" 0
-An array of pulsed to be added to a waveform.
+An array of pulses to be added to a waveform.
 
 .br
 
@@ -3270,10 +3309,6 @@ The speed in bits per second to use for the SPI device.
 
 .br
 
-.br
-
-.br
-
 .IP "\fBspi_channel\fP" 0
 A SPI channel, 0 or 1.
 
@@ -3282,64 +3317,7 @@ A SPI channel, 0 or 1.
 .br
 
 .IP "\fBspi_flags\fP" 0
-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.
+See \fBspi_open\fP.
 
 .br
 
index 2e4927f185e2ca86adf1a3f70e00764f90c97917..1524481f57427b8b24a00d82b0400efb1b99f1b2 100644 (file)
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 For more information, please refer to <http://unlicense.org/>
 */
 
-/* PIGPIOD_IF_VERSION 8 */
+/* PIGPIOD_IF_VERSION 9 */
 
 #include <stdio.h>
 #include <stdlib.h>
index e62ff8367bb6d134a24b3b594cf2d97d5c1ce101..89affb44db012d153442967dd5e8dbd682059589 100644 (file)
@@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
 
 #include "pigpio.h"
 
-#define PIGPIOD_IF_VERSION 8
+#define PIGPIOD_IF_VERSION 9
 
 /*TEXT
 
@@ -1564,6 +1564,10 @@ 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.
 
+An auxiliary SPI device is available on the B+ and may be
+selected by setting the A bit in the flags.  The auxiliary
+device has 3 chip selects and a selectable word size in bits.
+
 . .
 spi_channel: 0-1.
    spi_baud: >1.
@@ -1571,13 +1575,13 @@ spi_channel: 0-1.
 . .
 
 Returns a handle (>=0) if OK, otherwise PI_BAD_SPI_CHANNEL,
-PI_BAD_SPI_SPEED, PI_BAD_FLAGS, or PI_SPI_OPEN_FAILED.
+PI_BAD_SPI_SPEED, PI_BAD_FLAGS, PI_NO_AUX_SPI, or PI_SPI_OPEN_FAILED.
 
-spiFlags consists of the least significant 8 bits.
+spi_flags consists of the least significant 22 bits.
 
 . .
-7 6 5 4 3 2 1 0
-n n n n W P m m
+21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+ b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
 . .
 
 mm defines the SPI mode.
@@ -1590,13 +1594,30 @@ Mode POL PHA
  3    1   1
 . .
 
-P is 0 for active low chip select (normal) and 1 for active high.
+px is 0 if CEx is active low (default) and 1 for active high.
+
+ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise.
 
-W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+A is 0 for the standard SPI device, 1 for the auxiliary SPI.  The
+auxiliary device is only present on the B+.
+
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.  Standard
+SPI device only.
 
 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.
+if W is not set.  Standard SPI device only.
+
+T is 1 if the least significant bit is transmitted on MOSI first, the
+default (0) shifts the most significant bit out first.  Auxiliary SPI
+device only.
+
+R is 1 if the least significant bit is received on MISO first, the
+default (0) receives the most significant bit first.  Auxiliary SPI
+device only.
+
+bbbbbb defines the word size in bits (0-32).  The default (0)
+sets 8 bits per word.  Auxiliary SPI device only.
 
 The other bits in flags should be set to zero.
 D*/
@@ -2047,7 +2068,7 @@ pulseLen::
 1-100, the length of a trigger pulse in microseconds.
 
 *pulses::
-An array of pulsed to be added to a waveform.
+An array of pulses to be added to a waveform.
 
 pulsewidth::0, 500-2500
 . .
@@ -2095,37 +2116,11 @@ A standard type used to indicate the size of an object in bytes.
 spi_baud::
 The speed in bits per second to use for the SPI device.
 
-
 spi_channel::
 A SPI channel, 0 or 1.
 
 spi_flags::
-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.
+See [*spi_open*].
 
 *str::
  An array of characters.
diff --git a/pigs.1 b/pigs.1
index d3ad8a35bac4f38ee266a452607149ff71928c3e..251312d638201bca07e77d37a932ebecc3e88b46 100644 (file)
--- a/pigs.1
+++ b/pigs.1
@@ -1337,8 +1337,7 @@ The frequencies for each sample rate are:
  5us  8000  4000  2000 1600 1000  800  500  400  320
  8us  5000  2500  1250 1000  625  500  313  250  200
 10us  4000  2000  1000  800  500  400  250  200  160
-                                                   
-.br
+                                                
        #10   #11   #12  #13  #14  #15  #16  #17  #18
  1us  1250  1000   800  500  400  250  200  100   50
  2us   625   500   400  250  200  125  100   50   25
@@ -2168,8 +2167,7 @@ will be returned.
 .IP "" 4
 
 .br
-This command returns a handle to a SPI device on channel \fBc\fP. 
-.br
+This command returns a handle to a SPI device on channel \fBc\fP.
 
 .br
 Data will be transferred at \fBb\fP bits per second.  The flags \fBspf\fP
@@ -2177,14 +2175,19 @@ 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.
+An auxiliary SPI device is available on the B+ and may be
+selected by setting the A bit in the flags.  The auxiliary
+device has 3 chip selects and a selectable word size in bits.
+
+.br
+The flags consists of the least significant 22 bits.
 
 .br
 
 .EX
-7 6 5 4 3 2 1 0
+21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
 .br
-n n n n W P m m
+ b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
 .br
 
 .EE
@@ -2209,15 +2212,37 @@ Mode POL PHA
 .EE
 
 .br
-P is 0 for active low chip select (normal) and 1 for active high.
+px is 0 if CEx is active low (default) and 1 for active high.
 
 .br
-W is 0 if the device is not 3-wire, 1 if the device is 3-wire.
+ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise.
+
+.br
+A is 0 for the standard SPI device, 1 for the auxiliary SPI.  The
+auxiliary device is only present on the B+.
+
+.br
+W is 0 if the device is not 3-wire, 1 if the device is 3-wire.  Standard
+SPI device only.
 
 .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.
+if W is not set.  Standard SPI device only.
+
+.br
+T is 1 if the least significant bit is transmitted on MOSI first, the
+default (0) shifts the most significant bit out first.  Auxiliary SPI
+device only.
+
+.br
+R is 1 if the least significant bit is received on MISO first, the
+default (0) receives the most significant bit first.  Auxiliary SPI
+device only.
+
+.br
+bbbbbb defines the word size in bits (0-32).  The default (0)
+sets 8 bits per word.  Auxiliary SPI device only.
 
 .br
 The other bits in flags should be set to zero.
@@ -3187,50 +3212,7 @@ The command expects a script id as returned by a call to \fBPROC\fP.
 .br
 
 .IP "\fBspf\fP - SPI flags (32 bits)" 0
-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.
+See \fBSPIO\fP.
 
 .br
 
index 84dd5da0fc230eae87c0f9c39e6d8060e743229b..f483a931369682b9ac98c5640cfe1e062be69d1e 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 from distutils.core import setup
 
 setup(name='pigpio',
-      version='1.10',
+      version='1.11',
       author='joan',
       author_email='joan@abyz.co.uk',
       maintainer='joan',
diff --git a/x_pigs b/x_pigs
index d2d9b9d3c8c38a756a7e330684da291e986ce2d1..4991cc12190b7acef6dffdf67ff946959907dcb0 100755 (executable)
--- 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 = 20 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
+if [[ $s = 21 ]]; 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 0e9f87731dd32980ddfbfc3b8c550c23653e3680..2ae35990e82becd7de48e1274dc96b21ef3f8fc7 100755 (executable)
--- 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/pigout
-if [[ $s = 20 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
+if [[ $s = 21 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
 
 echo "prs $GPIO 255" >/dev/pigpio
 read -t 1 s </dev/pigout