{PI_CMD_BI2CO, "BI2CO", 131, 0}, // bbI2COpen
{PI_CMD_BI2CZ, "BI2CZ", 193, 6}, // bbI2CZip
+ {PI_CMD_BSPIC, "BSPIC", 112, 0}, // bbSPIClose
+ {PI_CMD_BSPIO, "BSPIO", 134, 0}, // bbSPIOpen
+ {PI_CMD_BSPIX, "BSPIX", 193, 6}, // bbSPIXfer
+
{PI_CMD_BR1, "BR1", 101, 3}, // gpioRead_Bits_0_31
{PI_CMD_BR2, "BR2", 101, 3}, // gpioRead_Bits_32_53
BI2CC sda Close bit bang I2C\n\
BI2CO sda scl baud | Open bit bang I2C\n\
BI2CZ sda ... I2C bit bang multiple transactions\n\
+\n\
+BSPIC cs Close bit bang SPI\n\
+BSPIO cs miso mosi sclk baud flag | Open bit bang SPI\n\
+BSPIX cs ... SPI bit bang transfer\n\
+\n\
BR1 Read bank 1 GPIO\n\
BR2 Read bank 2 GPIO\n\
BS1 bits Set GPIO in bank 1\n\
{PI_FILE_IS_A_DIR , "file is a directory"},
{PI_BAD_SHELL_STATUS , "bad shell return status"},
{PI_BAD_SCRIPT_NAME , "bad script name"},
+ {PI_BAD_SPI_BAUD , "bad SPI baud rate, not 50-500k"},
+ {PI_NOT_SPI_GPIO , "no bit bang SPI in progress on GPIO"},
};
char *p8;
int32_t *p32;
char c;
- uint32_t tp1=0, tp2=0, tp3=0;
- int8_t to1, to2, to3;
+ uint32_t tp1=0, tp2=0, tp3=0, tp4=0, tp5=0;
+ int8_t to1, to2, to3, to4, to5;
int eaten;
/* Check that ext is big enough for the largest message. */
case 112: /* BI2CC FC GDC GPW I2CC I2CRB
MG MICS MILS MODEG NC NP PADG PFG PRG
PROCD PROCP PROCS PRRG R READ SLRC SPIC
- WVDEL WVSC WVSM WVSP WVTX WVTXR
+ WVDEL WVSC WVSM WVSP WVTX WVTXR BSPIC
One positive parameter.
*/
break;
+ case 134: /* BSPIO
+
+ Six parameters. First to Fifth positive.
+ Sixth may be negative when interpreted as an int.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
+ ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
+ ctl->eaten += getNum(buf+ctl->eaten, &tp2, &to2);
+ ctl->eaten += getNum(buf+ctl->eaten, &tp3, &to3);
+ ctl->eaten += getNum(buf+ctl->eaten, &tp4, &to4);
+ ctl->eaten += getNum(buf+ctl->eaten, &tp5, &to5);
+
+ if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
+ (to1 == CMD_NUMERIC) && ((int)tp1 >= 0) &&
+ (to2 == CMD_NUMERIC) && ((int)tp2 >= 0) &&
+ (to3 == CMD_NUMERIC) && ((int)tp3 >= 0) &&
+ (to4 == CMD_NUMERIC) && ((int)tp4 >= 0) &&
+ (to5 == CMD_NUMERIC))
+ {
+ p[3] = 5 * 4;
+ memcpy(ext, &tp1, 4);
+ memcpy(ext, &tp2, 4);
+ memcpy(ext, &tp3, 4);
+ memcpy(ext, &tp4, 4);
+ memcpy(ext, &tp5, 4);
+ valid = 1;
+ }
+
+ break;
+
case 191: /* PROCR
One to 11 parameters, first positive,
break;
case 193: /* BI2CZ FW I2CWD I2CZ SERW SPIW SPIX
+ BSPIX
Two or more parameters, first >=0, rest 0-255.
*/
#define PI_NOTIFY_RUNNING 3
#define PI_NOTIFY_PAUSED 4
-#define PI_WFRX_NONE 0
-#define PI_WFRX_SERIAL 1
-#define PI_WFRX_I2C 2
-#define PI_WFRX_I2C_CLK 3
+#define PI_WFRX_NONE 0
+#define PI_WFRX_SERIAL 1
+#define PI_WFRX_I2C 2
+#define PI_WFRX_I2C_CLK 3
+#define PI_WFRX_SPI_MISO 4
+#define PI_WFRX_SPI_MOSI 5
+#define PI_WFRX_SPI_CS 6
+#define PI_WFRX_SPI_SCLK 7
#define PI_WF_MICROS 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)
+#define PI_SPI_FLAGS_GET_CPHA(x) ((x)&1)
+#define PI_SPI_FLAGS_GET_CPOL(x) ((x)&2)
#define PI_STARTING 0
#define PI_RUNNING 1
int started;
} wfRxI2C_t;
+typedef struct
+{
+ int MISO;
+ int MOSI;
+ int CS;
+ int SCLK;
+ int delay;
+ int spiFlags;
+ int MISOMode;
+ int MOSIMode;
+ int CSMode;
+ int SCLKMode;
+ int started;
+} wfRxSPI_t;
+
typedef struct
{
int mode;
{
wfRxSerial_t s;
wfRxI2C_t I;
+ wfRxSPI_t S;
};
} wfRx_t;
{
int res, i, j;
uint32_t mask;
- uint32_t tmp1, tmp2, tmp3;
+ uint32_t tmp1, tmp2, tmp3, tmp4, tmp5;
gpioPulse_t *pulse;
int masked;
-
res = 0;
switch (p[0])
}
break;
- case PI_CMD_BI2CC: res = bbI2CClose(p[1]); break;
+ case PI_CMD_BI2CC:
+ res = bbI2CClose(p[1]);
+ break;
case PI_CMD_BI2CO:
memcpy(&p[4], buf, 4);
}
break;
+ case PI_CMD_BSPIO:
+ memcpy(&tmp1, buf, 4); // MISO
+ memcpy(&tmp2, buf+4, 4); // MOSI
+ memcpy(&tmp3, buf+8, 4); // SCLK
+ memcpy(&tmp4, buf+12, 4);// baud
+ memcpy(&tmp5, buf+16, 4);// flags
+
+ res = bbSPIOpen(p[1], tmp1, tmp2, tmp3, tmp4, tmp5);
+ break;
+
+ case PI_CMD_BSPIC:
+ res = bbSPIClose(p[1]);
+ break;
+
+ case PI_CMD_BSPIX:
+ if (p[3] > bufSize) p[3] = bufSize;
+ res = bbSPIXfer(p[1], buf, buf, p[3]);
+ break;
+
case PI_CMD_BR1: res = gpioRead_Bits_0_31(); break;
case PI_CMD_BR2: res = gpioRead_Bits_32_53(); break;
}
break;
-
-
case PI_CMD_MICS:
if (p[1] <= PI_MAX_MICS_DELAY) myGpioDelay(p[1]);
else res = PI_BAD_MICS_DELAY;
case PI_CMD_SLRC: res = gpioSerialReadClose(p[1]); break;
case PI_CMD_SLRO:
- memcpy(&p[4], buf, 4);
- res = gpioSerialReadOpen(p[1], p[2], p[4]); break;
+ memcpy(&p[4], buf, 4);
+ res = gpioSerialReadOpen(p[1], p[2], p[4]); break;
case PI_CMD_SLRI: res = gpioSerialReadInvert(p[1], p[2]); break;
-
- case PI_CMD_SPIC: res = spiClose(p[1]); break;
+ case PI_CMD_SPIC:
+ res = spiClose(p[1]);
+ break;
case PI_CMD_SPIO:
memcpy(&p[4], buf, 4);
case PI_CMD_SLR:
case PI_CMD_SPIX:
case PI_CMD_SPIR:
+ case PI_CMD_BSPIX:
if (((int)p[3]) > 0)
{
return gpioRead(w->I.SDA);
}
+static void set_CS(wfRx_t *w)
+{
+ myGpioWrite(w->S.CS, PI_SPI_FLAGS_GET_CSPOLS(w->S.spiFlags));
+}
+
+static void clear_CS(wfRx_t *w)
+{
+ myGpioWrite(w->S.CS, !PI_SPI_FLAGS_GET_CSPOLS(w->S.spiFlags));
+}
+
+static void set_SCLK(wfRx_t *w)
+{
+ myGpioWrite(w->S.SCLK, !PI_SPI_FLAGS_GET_CPOL(w->S.spiFlags));
+}
+
+static void clear_SCLK(wfRx_t *w)
+{
+ myGpioWrite(w->S.SCLK, PI_SPI_FLAGS_GET_CPOL(w->S.spiFlags));
+}
+
static void set_SDA(wfRx_t *w)
{
myGpioSetMode(w->I.SDA, PI_INPUT);
myGpioDelay(w->I.delay);
}
+static void SPI_delay(wfRx_t *w)
+{
+ myGpioDelay(w->S.delay);
+}
+
static void I2C_clock_stretch(wfRx_t *w)
{
uint32_t now, max_stretch=10000;
while ((gpioRead(w->I.SCL) == 0) && ((gpioTick()-now) < max_stretch));
}
+static void bbSPIStart(wfRx_t *w)
+{
+ if (w->S.started)
+ {
+ clear_SCLK(w);
+ clear_CS(w);
+ SPI_delay(w);
+ }
+
+ clear_SCLK(w);
+ set_CS(w);
+
+ w->S.started = 1;
+}
+
+static void bbSPIStop(wfRx_t *w)
+{
+ clear_CS(w);
+ clear_SCLK(w);
+ SPI_delay(w);
+
+ w->S.started = 0;
+}
+
static void I2CStart(wfRx_t *w)
{
if (w->I.started)
return byte;
}
+static uint8_t bbSPIXferByte(wfRx_t *w, char txByte)
+{
+ uint8_t bit, rxByte=0;
+
+ if (PI_SPI_FLAGS_GET_CPHA(w->S.spiFlags))
+ {
+ for (bit=0; bit<8; bit++)
+ {
+ if (PI_SPI_FLAGS_GET_TX_LSB(w->S.spiFlags))
+ {
+ myGpioWrite(w->S.MOSI, txByte & 0x01);
+ txByte >>= 1;
+ }
+ else
+ {
+ myGpioWrite(w->S.MOSI, txByte & 0x80);
+ txByte <<= 1;
+ }
+ set_SCLK(w);
+ SPI_delay(w);
+
+ if (PI_SPI_FLAGS_GET_RX_LSB(w->S.spiFlags))
+ {
+ rxByte = (rxByte >> 1) | myGpioRead(w->S.MISO) << 7;
+ }
+ else
+ {
+ rxByte = (rxByte << 1) | myGpioRead(w->S.MISO);
+ }
+ clear_SCLK(w);
+ SPI_delay(w);
+ }
+ }
+ else
+ {
+ for (bit=0; bit<8; bit++)
+ {
+ if (PI_SPI_FLAGS_GET_TX_LSB(w->S.spiFlags))
+ {
+ myGpioWrite(w->S.MOSI, txByte & 0x01);
+ txByte >>= 1;
+ }
+ else
+ {
+ myGpioWrite(w->S.MOSI, txByte & 0x80);
+ txByte <<= 1;
+ }
+ if (PI_SPI_FLAGS_GET_RX_LSB(w->S.spiFlags))
+ {
+ rxByte = (rxByte >> 1) | myGpioRead(w->S.MISO) << 7;
+ }
+ else
+ {
+ rxByte = (rxByte << 1) | myGpioRead(w->S.MISO);
+ }
+ set_SCLK(w);
+ SPI_delay(w);
+ clear_SCLK(w);
+ SPI_delay(w);
+ }
+ }
+
+ return rxByte;
+}
+
int bbI2COpen(unsigned SDA, unsigned SCL, unsigned baud)
{
DBG(DBG_USER, "SDA=%d SCL=%d baud=%d", SDA, SCL, baud);
wfRx[SDA].I.started = 0;
wfRx[SDA].I.SDA = SDA;
wfRx[SDA].I.SCL = SCL;
- wfRx[SDA].I.delay = 500000 / baud;
+ wfRx[SDA].I.delay = (500000 / baud) - 1;
wfRx[SDA].I.SDAMode = gpioGetMode(SDA);
wfRx[SDA].I.SCLMode = gpioGetMode(SCL);
return 0;
}
+int bbSPIOpen(unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK, unsigned baud, unsigned spiFlags)
+{
+ DBG(DBG_USER, "MISO=%d MOSI=%d CS=%d SCLK=%d baud=%d", MISO, MOSI, CS, SCLK, baud);
+
+ CHECK_INITED;
+
+ if (CS > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad CS (%d)", CS);
+
+ if (MISO > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad MISO (%d)", MISO);
+
+ if (MOSI > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad MOSI (%d)", MOSI);
+
+ if (SCLK > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCLK (%d)", SCLK);
+
+ if ((baud < PI_BB_SPI_MIN_BAUD) || (baud > PI_BB_SPI_MAX_BAUD))
+ SOFT_ERROR(PI_BAD_SPI_BAUD,
+ "CS %d, bad baud rate (%d)", CS, baud);
+
+ if (wfRx[CS].mode != PI_WFRX_NONE)
+ SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used, mode %d", CS, wfRx[CS].mode);
+
+ if (!((wfRx[MISO].mode == PI_WFRX_NONE) || (wfRx[MISO].mode == PI_WFRX_SPI_MISO)) || (MISO == CS))
+ SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used, mode %d", MISO, wfRx[MISO].mode);
+
+ if (!((wfRx[MOSI].mode == PI_WFRX_NONE) || (wfRx[MOSI].mode == PI_WFRX_SPI_MOSI)) || (MOSI == CS) || (MOSI == MISO))
+ SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used, mode %d", MOSI, wfRx[MOSI].mode);
+
+ if (!((wfRx[SCLK].mode == PI_WFRX_NONE) || (wfRx[SCLK].mode == PI_WFRX_SPI_SCLK)) || (SCLK == CS) || (SCLK == MISO) || (SCLK == MOSI))
+ SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used, mode %d", SCLK, wfRx[SCLK].mode);
+
+ wfRx[MISO].gpio = MISO;
+ wfRx[MISO].mode = PI_WFRX_SPI_MISO;
+
+ wfRx[MOSI].gpio = MOSI;
+ wfRx[MOSI].mode = PI_WFRX_SPI_MOSI;
+
+ wfRx[SCLK].gpio = SCLK;
+ wfRx[SCLK].mode = PI_WFRX_SPI_SCLK;
+
+ wfRx[CS].gpio = CS;
+ wfRx[CS].mode = PI_WFRX_SPI_CS;
+ wfRx[CS].baud = baud;
+
+ wfRx[CS].S.started = 0;
+ wfRx[CS].S.MISO = MISO;
+ wfRx[CS].S.MOSI = MOSI;
+ wfRx[CS].S.CS = CS;
+ wfRx[CS].S.SCLK = SCLK;
+ wfRx[CS].S.delay = 500000 / baud;
+ wfRx[CS].S.spiFlags = spiFlags;
+ wfRx[CS].S.MISOMode = gpioGetMode(MISO);
+ wfRx[CS].S.MOSIMode = gpioGetMode(MOSI);
+ wfRx[CS].S.CSMode = gpioGetMode(CS);
+ wfRx[CS].S.SCLKMode = gpioGetMode(SCLK);
+
+ myGpioSetMode(MISO, PI_INPUT);
+ myGpioSetMode(MOSI, PI_OUTPUT);
+ myGpioSetMode(CS, PI_OUTPUT);
+ myGpioSetMode(SCLK, PI_OUTPUT);
+
+ return 0;
+}
+
/* ----------------------------------------------------------------------- */
return 0;
}
+int bbSPIClose(unsigned CS)
+{
+ DBG(DBG_USER, "CS=%d", CS);
+
+ CHECK_INITED;
+
+ if (CS > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", CS);
+
+ switch(wfRx[CS].mode)
+ {
+ case PI_WFRX_SPI_CS:
+
+ myGpioSetMode(wfRx[CS].S.MISO, wfRx[CS].S.MISOMode);
+ myGpioSetMode(wfRx[CS].S.MOSI, wfRx[CS].S.MOSIMode);
+ myGpioSetMode(wfRx[CS].S.CS, wfRx[CS].S.CSMode);
+ myGpioSetMode(wfRx[CS].S.SCLK, wfRx[CS].S.SCLKMode);
+
+ wfRx[wfRx[CS].S.MISO].mode = PI_WFRX_NONE;
+ wfRx[wfRx[CS].S.MOSI].mode = PI_WFRX_NONE;
+ wfRx[wfRx[CS].S.CS].mode = PI_WFRX_NONE;
+ wfRx[wfRx[CS].S.SCLK].mode = PI_WFRX_NONE;
+
+ break;
+
+ default:
+
+ SOFT_ERROR(PI_NOT_SPI_GPIO, "no SPI on gpio (%d)", CS);
+
+ break;
+
+ }
+
+ return 0;
+}
+/*-------------------------------------------------------------------------*/
+
+int bbSPIXfer(
+ unsigned CS,
+ char *inBuf,
+ char *outBuf,
+ unsigned len)
+{
+ int pos, status;
+ wfRx_t *w;
+
+ DBG(DBG_USER, "gpio=%d inBuf=%s outBuf=%08X len=%d",
+ CS, myBuf2Str(len, (char *)inBuf), (int)outBuf, len);
+
+ CHECK_INITED;
+
+ if (CS > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", CS);
+
+ if (wfRx[CS].mode != PI_WFRX_SPI_CS)
+ SOFT_ERROR(PI_NOT_SPI_GPIO, "no SPI on gpio (%d)", CS);
+
+ if (!inBuf || !len)
+ SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
+
+ if (!outBuf && len)
+ SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
+
+ w = &wfRx[CS];
+
+ status = 0;
+
+ bbSPIStart(w);
+ for (pos=0; pos < len; pos++)
+ {
+ DBG(DBG_INTERNAL, "pos=%d len=%d sent=%d",
+ pos, len, inBuf[pos]);
+ outBuf[pos] = bbSPIXferByte(w, inBuf[pos]);
+ DBG(DBG_INTERNAL, "recvd=%d", outBuf[pos]);
+ }
+ bbSPIStop(w);
+
+ status = len;
+
+ return status;
+}
/*-------------------------------------------------------------------------*/
int bbI2CZip(
spiWrite Writes bytes to a SPI device
spiXfer Transfers bytes with a SPI device
+bbSPIOpen Opens GPIO for bit banging SPI
+bbSPIClose Closes GPIO for bit banging SPI
+bbSPIXfer Performs multiple bit banged SPI transactions
+
SERIAL
serOpen Opens a serial device
#define PI_BB_I2C_MIN_BAUD 50
#define PI_BB_I2C_MAX_BAUD 500000
+#define PI_BB_SPI_MIN_BAUD 50
+#define PI_BB_SPI_MAX_BAUD 500000
+
#define PI_BB_SER_MIN_BAUD 50
#define PI_BB_SER_MAX_BAUD 250000
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_I2C_GPIO.
D*/
+/*F*/
+int bbSPIOpen(unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK, unsigned baud, unsigned spiFlags);
+/*D
+This function selects a set of GPIO for bit banging SPI at a
+specified baud rate.
+
+Bit banging SPI allows the use of different GPIO for SPI than
+for the hardware SPI ports.
+
+. .
+ CS: 0-31
+ MISO: 0-31
+ MOSI: 0-31
+ SCLK: 0-31
+baud: 50-500000
+spiFlags: see below
+. .
+spiFlags consists of the least significant 22 bits.
+
+. .
+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
+. .
+
+p0 is 0 if CEx is active low (default) and 1 for active high.
+
+The other bits in flags should be set to zero.
+
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_SPI_BAUD, or
+PI_GPIO_IN_USE.
+D*/
+
+/*F*/
+int bbSPIClose(unsigned CS);
+/*D
+This function stops bit banging SPI on a set of GPIO previously
+opened with [*bbSPIOpen*].
+
+. .
+CS: 0-31, the CS GPIO used in a prior call to [*bbSPIOpen*]
+. .
+
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SPI_GPIO.
+D*/
+
+/*F*/
+int bbSPIXfer(
+ unsigned CS,
+ char *inBuf,
+ char *outBuf,
+ unsigned len);
+/*D
+This function executes an bit banged SPI transfer. The data
+to be sent is specified by the contents of inBuf, received data
+is stored into outBuf.
+len specifies the amount of bytes to be transferred.
+
+. .
+ CS: 0-31 (as used in a prior call to [*bbSPIOpen*])
+ inBuf: pointer to buffer to hold data to be sent
+outBuf: pointer to buffer to hold returned data
+outLen: size of output buffer
+. .
+
+Returns >= 0 if OK (the number of bytes read), otherwise
+PI_BAD_USER_GPIO, PI_NOT_SPI_GPIO or PI_BAD_POINTER.
+
+The returned I2C data is stored in consecutive locations of outBuf.
+D*/
+
/*F*/
int bbI2CZip(
unsigned SDA,
#define PI_CMD_SHELL 110
+#define PI_CMD_BSPIC 111
+#define PI_CMD_BSPIO 112
+#define PI_CMD_BSPIX 113
+
/*DEF_E*/
/*
#define PI_FILE_IS_A_DIR -138 // file is a directory
#define PI_BAD_SHELL_STATUS -139 // bad shell return status
#define PI_BAD_SCRIPT_NAME -140 // bad script name
+#define PI_BAD_SPI_BAUD -141 // bad SPI baud rate, not 50-500k
+#define PI_NOT_SPI_GPIO -142 // no bit bang SPI in progress on GPIO
#define PI_PIGIF_ERR_0 -2000
#define PI_PIGIF_ERR_99 -2099
spi_write Writes bytes to a SPI device
spi_xfer Transfers bytes with a SPI device
+bb_spi_open Opens GPIO for bit banging SPI
+bb_spi_close Closes GPIO for bit banging SPI
+bb_spi_xfer Transfers bytes with bit banging SPI
+
Serial
serial_open Opens a serial device
_PI_CMD_FL =109
_PI_CMD_SHELL=110
+_PI_CMD_BSPIC=111
+_PI_CMD_BSPIO=112
+_PI_CMD_BSPIX=113
+
# pigpio error numbers
_PI_INIT_FAILED =-1
PI_FILE_IS_A_DIR =-138
PI_BAD_SHELL_STATUS =-139
PI_BAD_SCRIPT_NAME =-140
+PI_BAD_SPI_BAUD =-141
+PI_NOT_SPI_GPIO =-142
# pigpio error text
[PI_FILE_IS_A_DIR , "file is a directory"],
[PI_BAD_SHELL_STATUS , "bad shell return status"],
[PI_BAD_SCRIPT_NAME , "bad script name"],
-
+ [PI_BAD_SPI_BAUD , "bad SPI baud rate, not 50-500k"],
+ [PI_NOT_SPI_GPIO , "no bit bang SPI in progress on GPIO"],
]
class _socklock:
return bytes, data
+ def bb_spi_open(self, CS, MISO, MOSI, SCLK, baud=100000, spi_flags=1):
+ """
+###
+ """
+ # I p1 CS
+ # I p2 0
+ # I p3 20
+ ## extension ##
+ # I MISO
+ # I MOSI
+ # I SCLK
+ # I baud
+ # I spi_flags
+
+ extents = [struct.pack("IIIII", MISO, MOSI, SCLK, baud, spi_flags)]
+ return _u2i(_pigpio_command_ext(
+ self.sl, _PI_CMD_BSPIO, CS, 0, 20, extents))
+
+
+ def bb_spi_close(self, CS):
+ """
+ This function stops bit banging SPI on a set of GPIO
+ previously opened with [*bb_spi_open*].
+
+ CS:= 0-31, the CS GPIO used in a prior call to [*bb_ispi_open*]
+
+ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SPI_GPIO.
+
+ ...
+ pi.bb_spi_close(CS)
+ ...
+ """
+ return _u2i(_pigpio_command(self.sl, _PI_CMD_BSPIC, CS, 0))
+
+
+ def bb_spi_xfer(self, CS, data):
+ """
+###
+ """
+ # I p1 SDA
+ # I p2 0
+ # I p3 len
+ ## extension ##
+ # s len data bytes
+
+ # Don't raise exception. Must release lock.
+ bytes = u2i(_pigpio_command_ext(
+ self.sl, _PI_CMD_BSPIX, CS, 0, len(data), [data], False))
+ if bytes > 0:
+ data = self._rxbuf(bytes)
+ else:
+ data = ""
+ self.sl.l.release()
+ return bytes, data
+
+
def bb_i2c_open(self, SDA, SCL, baud=100000):
"""
This function selects a pair of GPIO for bit banging I2C at a