From f51cd7e950c08c7460fda84372a2d6552416762b Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Wed, 23 Dec 2020 23:08:11 -0600 Subject: [PATCH] Fix GPIO for BSC SPI in slave mode and update doc sources. --- DOC/src/defs/pigs.def | 36 +++++++++++++++++++++++++---- pigpio.c | 37 ++++++++++++++++++++--------- pigpio.h | 30 ++++++++++++++++-------- pigpio.py | 54 ++++++++++++++++++++++++++++++++++++------- pigpiod_if2.h | 18 +++++++++++---- 5 files changed, 136 insertions(+), 39 deletions(-) diff --git a/DOC/src/defs/pigs.def b/DOC/src/defs/pigs.def index f678126..5c98e97 100644 --- a/DOC/src/defs/pigs.def +++ b/DOC/src/defs/pigs.def @@ -524,9 +524,6 @@ The output process is simple. You simply append data to the FIFO buffer on the chip. This works like a queue, you add data to the queue and the master removes it. -I can't get SPI to work properly. I tried with a -control word of 0x303 and swapped MISO and MOSI. - The command sets the BSC mode and writes any data [*bvs*] to the BSC transmit FIFO. It returns the data count (at least 1 for the status word), the status word, followed by any data bytes @@ -543,13 +540,13 @@ GPIO used for models other than those based on the BCM2711. @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 18 @ 19 @ - @ - @ - @ - -SPI @ - @ - @ 18 @ 19 @ 20 @ 21 +SPI @ - @ - @ 20 @ 19 @ 18 @ 21 GPIO used for models based on the BCM2711 (e.g. the Pi4B). @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 10 @ 11 @ - @ - @ - @ - -SPI @ - @ - @ 10 @ 11 @ 9 @ 8 +SPI @ - @ - @ 9 @ 11 @ 10 @ 8 When a zero control word is received the used GPIO will be reset to INPUT mode. @@ -647,6 +644,35 @@ $ pigs i2crd 0 5 5 22 33 44 55 66 ... +The BSC slave in SPI mode deserializes data from the MOSI pin into its receiver/ +FIFO when the LSB of the first byte is a 0. No data is output on the MISO pin. +When the LSB of the first byte on MOSI is a 1, the transmitter/FIFO data is +serialized onto the MISO pin while all other data on the MOSI pin is ignored. + +The BK bit of the BSC control register is non-functional when in the SPI mode. +The transmitter along with its FIFO can be dequeued by successively disabling +and re-enabling the TE bit on the BSC control register while in SPI mode. + +This example demonstrates a SPI master talking to the BSC as SPI slave: +Requires SPI master SCLK / MOSI / MISO / CE GPIO are connected to +BSC peripheral GPIO 11 / 9 / 10 / 8 respectively, on a Pi4B (BCM2711). + +... +$ pigs bspio 15 26 13 14 10000 0 # open bit-bang spi master on random gpio + +$ pigs bscx 0x303 # start BSC as SPI slave, both rx and tx enabled +1 18 + +$ pigs bspix 15 0 0xd 0xe 0xa 0xd # write 0xdead to BSC +5 0 0 0 0 0 + +$ pigs bscx 0x303 0xb 0xe 0xe 0xf # place 0xbeef in BSC tx FIFO, read rx FIFO +5 262338 13 14 10 13 + +$ pigs bspix 15 1 0 0 0 0 # read four bytes from BSC +5 0 11 14 14 15 +... + BSPIC :: This command stops bit banging SPI on a set of GPIO diff --git a/pigpio.c b/pigpio.c index af94c11..da42bfa 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 78 */ +/* pigpio version 7802 */ /* include ------------------------------------------------------- */ @@ -10924,7 +10924,7 @@ int bbI2CZip( void bscInit(int mode) { - int sda, scl, miso, ce; + int sda, scl, mosi, miso, ce; bscsReg[BSC_CR]=0; /* clear device */ bscsReg[BSC_RSR]=0; /* clear underrun and overrun errors */ @@ -10934,32 +10934,39 @@ void bscInit(int mode) if (pi_is_2711) { - sda = BSC_SDA_MOSI_2711; + sda = BSC_SDA_2711; scl = BSC_SCL_SCLK_2711; + mosi = BSC_MOSI_2711; miso = BSC_MISO_2711; ce = BSC_CE_N_2711; } else { - sda = BSC_SDA_MOSI; + sda = BSC_SDA; scl = BSC_SCL_SCLK; + mosi = BSC_MOSI; miso = BSC_MISO; ce = BSC_CE_N; } - gpioSetMode(sda, PI_ALT3); - gpioSetMode(scl, PI_ALT3); if (mode > 1) /* SPI uses all GPIO */ { + gpioSetMode(scl, PI_ALT3); + gpioSetMode(mosi, PI_ALT3); gpioSetMode(miso, PI_ALT3); gpioSetMode(ce, PI_ALT3); } + else + { + gpioSetMode(scl, PI_ALT3); + gpioSetMode(sda, PI_ALT3); + } } void bscTerm(int mode) { - int sda, scl, miso, ce; + int sda, scl, mosi, miso, ce; bscsReg[BSC_CR] = 0; /* clear device */ bscsReg[BSC_RSR]=0; /* clear underrun and overrun errors */ @@ -10967,27 +10974,35 @@ void bscTerm(int mode) if (pi_is_2711) { - sda = BSC_SDA_MOSI_2711; + sda = BSC_SDA_2711; scl = BSC_SCL_SCLK_2711; + mosi = BSC_MOSI_2711; miso = BSC_MISO_2711; ce = BSC_CE_N_2711; } else { - sda = BSC_SDA_MOSI; + sda = BSC_SDA; scl = BSC_SCL_SCLK; + mosi = BSC_MOSI; miso = BSC_MISO; ce = BSC_CE_N; } - gpioSetMode(sda, PI_INPUT); - gpioSetMode(scl, PI_INPUT); if (mode > 1) { + gpioSetMode(scl, PI_INPUT); + gpioSetMode(mosi, PI_INPUT); gpioSetMode(miso, PI_INPUT); gpioSetMode(ce, PI_INPUT); } + else + { + gpioSetMode(sda, PI_INPUT); + gpioSetMode(scl, PI_INPUT); + + } } int bscXfer(bsc_xfer_t *xfer) diff --git a/pigpio.h b/pigpio.h index bd5fbef..9b82271 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 7801 +#define PIGPIO_VERSION 7802 /*TEXT @@ -803,14 +803,16 @@ typedef void *(gpioThreadFunc_t) (void *); /* BSC GPIO */ -#define BSC_SDA_MOSI 18 +#define BSC_SDA 18 +#define BSC_MOSI 20 #define BSC_SCL_SCLK 19 -#define BSC_MISO 20 +#define BSC_MISO 18 #define BSC_CE_N 21 -#define BSC_SDA_MOSI_2711 10 +#define BSC_SDA_2711 10 +#define BSC_MOSI_2711 9 #define BSC_SCL_SCLK_2711 11 -#define BSC_MISO_2711 9 +#define BSC_MISO_2711 10 #define BSC_CE_N_2711 8 /* Longest busy delay */ @@ -2978,9 +2980,6 @@ The output process is simple. You simply append data to the FIFO buffer on the chip. This works like a queue, you add data to the queue and the master removes it. -I can't get SPI to work properly. I tried with a -control word of 0x303 and swapped MISO and MOSI. - The function sets the BSC mode, writes any data in the transmit buffer to the BSC transmit FIFO, and copies any data in the BSC receive FIFO to the @@ -3013,13 +3012,13 @@ GPIO used for models other than those based on the BCM2711. @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 18 @ 19 @ - @ - @ - @ - -SPI @ - @ - @ 18 @ 19 @ 20 @ 21 +SPI @ - @ - @ 20 @ 19 @ 18 @ 21 GPIO used for models based on the BCM2711 (e.g. the Pi4B). @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 10 @ 11 @ - @ - @ - @ - -SPI @ - @ - @ 10 @ 11 @ 9 @ 8 +SPI @ - @ - @ 9 @ 11 @ 10 @ 8 When a zero control word is received the used GPIO will be reset to INPUT mode. @@ -3099,6 +3098,17 @@ if (status >= 0) // process transfer } ... + +The BSC slave in SPI mode deserializes data from the MOSI pin into its +receiver/FIFO when the LSB of the first byte is a 0. No data is output on +the MISO pin. When the LSB of the first byte on MOSI is a 1, the +transmitter/FIFO data is serialized onto the MISO pin while all other data +on the MOSI pin is ignored. + +The BK bit of the BSC control register is non-functional when in the SPI +mode. The transmitter along with its FIFO can be dequeued by successively +disabling and re-enabling the TE bit on the BSC control register while in +SPI mode. D*/ /*F*/ diff --git a/pigpio.py b/pigpio.py index 9c9713c..20d48e6 100644 --- a/pigpio.py +++ b/pigpio.py @@ -3604,9 +3604,6 @@ class pi(): buffer on the chip. This works like a queue, you add data to the queue and the master removes it. - I can't get SPI to work properly. I tried with a - control word of 0x303 and swapped MISO and MOSI. - The function sets the BSC mode, writes any data in the transmit buffer to the BSC transmit FIFO, and copies any data in the BSC receive FIFO to the @@ -3627,13 +3624,13 @@ class pi(): @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 18 @ 19 @ - @ - @ - @ - - SPI @ - @ - @ 18 @ 19 @ 20 @ 21 + SPI @ - @ - @ 20 @ 19 @ 18 @ 21 GPIO used for models based on the BCM2711 (e.g. the Pi4B). @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 10 @ 11 @ - @ - @ - @ - - SPI @ - @ - @ 10 @ 11 @ 9 @ 8 + SPI @ - @ - @ 9 @ 11 @ 10 @ 8 When a zero control word is received the used GPIO will be reset to INPUT mode. @@ -3689,6 +3686,50 @@ class pi(): ... (status, count, data) = pi.bsc_xfer(0x330305, "Hello!") ... + + The BSC slave in SPI mode deserializes data from the MOSI pin into its + receiver/FIFO when the LSB of the first byte is a 0. No data is output on + the MISO pin. When the LSB of the first byte on MOSI is a 1, the + transmitter/FIFO data is serialized onto the MISO pin while all other data + on the MOSI pin is ignored. + + The BK bit of the BSC control register is non-functional when in the SPI + mode. The transmitter along with its FIFO can be dequeued by successively + disabling and re-enabling the TE bit on the BSC control register while in + SPI mode. + + This example demonstrates a SPI master talking to the BSC as SPI slave: + Requires SPI master SCLK / MOSI / MISO / CE GPIO are connected to + BSC peripheral GPIO 11 / 9 / 10 / 8 respectively, on a Pi4B (BCM2711). + + ... + #!/usr/bin/env python + + import pigpio + + # Choose some random GPIO for the bit-bang SPI master + CE=15 + MISO=26 + MOSI=13 + SCLK=14 + + pi = pigpio.pi() + if not pi.connected: + exit() + + pi.bb_spi_open(CE, MISO, MOSI, SCLK, 10000, 0) # open SPI master + pi.bsc_xfer(0x303, []) # start BSC as SPI slave + pi.bb_spi_xfer(CE, '\0' + 'hello') # write 'hello' to BSC + status, count, bsc_data = pi.bsc_xfer(0x303, 'world') + print bsc_data # hello + count, spi_data = pi.bb_spi_xfer(CE, [1,0,0,0,0,0]) + print spi_data # world + + pi.bsc_xfer(0, []) + pi.bb_spi_close(CE) + + pi.stop() + ... """ # I p1 control # I p2 0 @@ -3716,9 +3757,6 @@ class pi(): """ This function allows the Pi to act as a slave I2C device. - This function is not available on the BCM2711 (e.g. as - used in the Pi4B). - The data bytes (if any) are written to the BSC transmit FIFO and the bytes in the BSC receive FIFO are returned. diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 723c59d..b6aa648 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -3518,9 +3518,6 @@ The output process is simple. You simply append data to the FIFO buffer on the chip. This works like a queue, you add data to the queue and the master removes it. -I can't get SPI to work properly. I tried with a -control word of 0x303 and swapped MISO and MOSI. - The function sets the BSC mode, writes any data in the transmit buffer to the BSC transmit FIFO, and copies any data in the BSC receive FIFO to the @@ -3563,13 +3560,13 @@ GPIO used for models other than those based on the BCM2711. @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 18 @ 19 @ - @ - @ - @ - -SPI @ - @ - @ 18 @ 19 @ 20 @ 21 +SPI @ - @ - @ 20 @ 19 @ 18 @ 21 GPIO used for models based on the BCM2711 (e.g. the Pi4B). @ SDA @ SCL @ MOSI @ SCLK @ MISO @ CE I2C @ 10 @ 11 @ - @ - @ - @ - -SPI @ - @ - @ 10 @ 11 @ 9 @ 8 +SPI @ - @ - @ 9 @ 11 @ 10 @ 8 When a zero control word is received the used GPIO will be reset to INPUT mode. @@ -3640,6 +3637,17 @@ if (status >= 0) // process transfer } ... + +The BSC slave in SPI mode deserializes data from the MOSI pin into its +receiver/FIFO when the LSB of the first byte is a 0. No data is output on +the MISO pin. When the LSB of the first byte on MOSI is a 1, the +transmitter/FIFO data is serialized onto the MISO pin while all other data +on the MOSI pin is ignored. + +The BK bit of the BSC control register is non-functional when in the SPI +mode. The transmitter along with its FIFO can be dequeued by successively +disabling and re-enabling the TE bit on the BSC control register while in +SPI mode. D*/ /*F*/