From 5cf0d636957f9025cc6c59b828d84409d2079595 Mon Sep 17 00:00:00 2001 From: Eric Sorton Date: Sat, 29 Aug 2015 09:06:27 -0400 Subject: [PATCH] Option to invert bit bang serial. --- command.c | 6 +++++- pigpio.3 | 28 ++++++++++++++++++++++++++++ pigpio.c | 29 +++++++++++++++++++++++++++++ pigpio.h | 28 ++++++++++++++++++++++++++++ pigpio.py | 22 ++++++++++++++++++++++ pigpiod_if.3 | 20 ++++++++++++++++++++ pigpiod_if.c | 3 +++ pigpiod_if.h | 14 ++++++++++++++ pigs.1 | 30 ++++++++++++++++++++++++++++++ 9 files changed, 179 insertions(+), 1 deletion(-) diff --git a/command.c b/command.c index 41c35ff..4b52bec 100644 --- a/command.c +++ b/command.c @@ -146,6 +146,7 @@ cmdInfo_t cmdInfo[]= {PI_CMD_SLR, "SLR", 121, 6}, // gpioSerialRead {PI_CMD_SLRC, "SLRC", 112, 0}, // gpioSerialReadClose {PI_CMD_SLRO, "SLRO", 131, 0}, // gpioSerialReadOpen + {PI_CMD_SLRI, "SLRI", 121, 0}, // gpioSerialReadInvert {PI_CMD_SPIC, "SPIC", 112, 0}, // spiClose {PI_CMD_SPIO, "SPIO", 131, 2}, // spiOpen @@ -305,6 +306,7 @@ SERWB h byte Write byte to serial handle\n\ SLR g v Read bit bang serial data from gpio\n\ SLRC g Close gpio for bit bang serial data\n\ SLRO g baud bitlen | Open gpio for bit bang serial data\n\ +SLRI g invert Invert serial logic (1 invert, 0 normal)\n\ SPIC h SPI close handle\n\ SPIO channel baud flags | SPI open channel at baud with flags\n\ SPIR h v SPI read bytes from handle\n\ @@ -466,6 +468,8 @@ static errInfo_t errInfo[]= {PI_CHAIN_NESTING , "chain counters nested too deeply"}, {PI_CHAIN_TOO_BIG , "chain is too long"}, {PI_DEPRECATED , "deprecated function removed"}, + {PI_NOT_IN_SER_MODE , "gpio not opened for bit-bang serial"}, + {PI_BAD_SER_INVERT , "bit-bang serial invert not 0 or 1"}, }; @@ -662,7 +666,7 @@ int cmdParse( break; case 121: /* HC I2CRD I2CRR I2CRW I2CWB I2CWQ P PFS PRS - PWM S SERVO SLR W WDOG WRITE + PWM S SERVO SLR SLRI W WDOG WRITE Two positive parameters. */ diff --git a/pigpio.3 b/pigpio.3 index 0006337..9675778 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -2175,6 +2175,26 @@ For \fBdata_bits\fP 9-16 there will be two bytes per character. .br For \fBdata_bits\fP 17-32 there will be four bytes per character. +.IP "\fBint gpioSerialReadInvert(unsigned user_gpio, unsigned invert)\fP" +.IP "" 4 +This function inverts the serial logic for bit bang reading of serial data. + +.br + +.br + +.EX +user_gpio: 0-31, previously opened with \fBgpioSerialReadOpen\fP. + invert: 0-1, 1 invert , 0 normal. +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_NOT_IN_SER_MODE or PI_BAD_SER_INVERT. + .IP "\fBint gpioSerialReadClose(unsigned user_gpio)\fP" .IP "" 4 This function closes a gpio for bit bang reading of serial data. @@ -7309,6 +7329,10 @@ A 16-bit word value. #define PI_CMD_WVCHA 93 .br +.br +#define PI_CMD_SLRI 94 +.br + .br #define PI_CMD_NOIB 99 .br @@ -7565,6 +7589,10 @@ A 16-bit word value. .br #define PI_DEPRECATED -120 // deprecated function removed .br +#define PI_NOT_IN_SER_MODE -121 // gpio not opened for bit-bang serial +.br +#define PI_BAD_SER_INVERT -122 // bit-bang serial invert not 0 or 1 +.br .br #define PI_PIGIF_ERR_0 -2000 diff --git a/pigpio.c b/pigpio.c index 2f43b95..47796f4 100644 --- a/pigpio.c +++ b/pigpio.c @@ -1011,6 +1011,7 @@ typedef struct int bytes; /* 1, 2, 4 */ int level; int dataBits; /* 1-32 */ + int invert; /* 0, 1 */ } wfRxSerial_t; typedef struct @@ -1943,6 +1944,7 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) 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; @@ -2696,6 +2698,8 @@ static void waveRxSerial(wfRx_t *w, int level, uint32_t tick) int diffTicks, lastLevel; int newWritePos; + level = level ^ w->s.invert; + if (w->s.bit >= 0) { diffTicks = tick - w->s.startBitTick; @@ -9311,6 +9315,7 @@ int gpioSerialReadOpen(unsigned gpio, unsigned baud, unsigned data_bits) wfRx[gpio].s.writePos = 0; wfRx[gpio].s.bit = -1; wfRx[gpio].s.dataBits = data_bits; + wfRx[gpio].s.invert = PI_BB_SER_NORMAL; if (data_bits < 9) wfRx[gpio].s.bytes = 1; else if (data_bits < 17) wfRx[gpio].s.bytes = 2; @@ -9323,6 +9328,30 @@ int gpioSerialReadOpen(unsigned gpio, unsigned baud, unsigned data_bits) /*-------------------------------------------------------------------------*/ +int gpioSerialReadInvert(unsigned gpio, unsigned invert) +{ + DBG(DBG_USER, "gpio=%d invert=%d", gpio, invert); + + CHECK_INITED; + + if (gpio > PI_MAX_USER_GPIO) + SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio); + + if (wfRx[gpio].mode != PI_WFRX_SERIAL) + SOFT_ERROR(PI_NOT_IN_SER_MODE, "gpio %d is not in serial mode", gpio); + + if ((invert < PI_BB_SER_NORMAL) || + (invert > PI_BB_SER_INVERT)) + SOFT_ERROR(PI_BAD_SER_INVERT, + "gpio %d, invert (%d)", gpio, invert); + + wfRx[gpio].s.invert = invert; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize) { unsigned bytes=0, wpos; diff --git a/pigpio.h b/pigpio.h index 99948e7..3a69e07 100644 --- a/pigpio.h +++ b/pigpio.h @@ -174,6 +174,7 @@ gpioNotifyPause Pause notifications gpioNotifyClose Close a notification gpioSerialReadOpen Opens a gpio for bit bang serial reads +gpioSerialReadInvert Configures normal/inverted for serial reads gpioSerialRead Reads bit bang serial data from a gpio gpioSerialReadClose Closes a gpio for bit bang serial reads @@ -549,6 +550,9 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_BB_SER_MIN_BAUD 50 #define PI_BB_SER_MAX_BAUD 250000 +#define PI_BB_SER_NORMAL 0 +#define PI_BB_SER_INVERT 1 + #define PI_WAVE_MIN_BAUD 50 #define PI_WAVE_MAX_BAUD 1000000 @@ -1821,6 +1825,26 @@ It is the caller's responsibility to read data from the cyclic buffer in a timely fashion. D*/ +/*F*/ +int gpioSerialReadInvert(unsigned user_gpio, unsigned invert); +/*D +This function configures the level logci for bit bang serial reads. + +Pass PI_BB_SER_INVERT to invert the serial logic. Pass PI_BB_SER_NORMAL for +normal logic. Default is PI_BB_SER_NORMAL. + +. . +user_gpio: 0-31 +invert: 0-1 +. . + +Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_GPIO_IN_USE, +PI_NOT_IN_SER_MODE, or PI_BAD_SER_INVERT. + +The gpio must be opened for bit bang reading of serial data using +[*gpioSerialReadOpen*] prior to calling this function. +D*/ + /*F*/ int gpioSerialRead(unsigned user_gpio, void *buf, size_t bufSize); @@ -4581,6 +4605,8 @@ PARAMS*/ #define PI_CMD_WVCHA 93 +#define PI_CMD_SLRI 94 + #define PI_CMD_NOIB 99 /*DEF_E*/ @@ -4766,6 +4792,8 @@ after this command is issued. #define PI_CHAIN_NESTING -118 // chain counters nested too deeply #define PI_CHAIN_TOO_BIG -119 // chain is too long #define PI_DEPRECATED -120 // deprecated function removed +#define PI_NOT_IN_SER_MODE -121 // gpio not opened for bit-bang serial +#define PI_BAD_SER_INVERT -122 // bit-bang serial invert not 0 or 1 #define PI_PIGIF_ERR_0 -2000 #define PI_PIGIF_ERR_99 -2099 diff --git a/pigpio.py b/pigpio.py index 28bff08..84e941d 100644 --- a/pigpio.py +++ b/pigpio.py @@ -151,6 +151,7 @@ notify_close Close a notification bb_serial_read_open Open a gpio for bit bang serial reads bb_serial_read Read bit bang serial data from a gpio bb_serial_read_close Close a gpio for bit bang serial reads +bb_serial_invert Invert serial logic (1 invert, 0 normal) hardware_clock Start hardware clock on supported gpios hardware_PWM Start hardware PWM on supported gpios @@ -432,6 +433,8 @@ _PI_CMD_I2CZ =92 _PI_CMD_WVCHA=93 +_PI_CMD_SLRI= 94 + # pigpio error numbers _PI_INIT_FAILED =-1 @@ -555,6 +558,8 @@ PI_BAD_CHAIN_DELAY =-117 PI_CHAIN_NESTING =-118 PI_CHAIN_TOO_BIG =-119 PI_DEPRECATED =-120 +PI_NOT_IN_SER_MODE =-121 +PI_BAD_SER_INVERT =-122 # pigpio error text @@ -677,6 +682,8 @@ _errors=[ [PI_CHAIN_NESTING , "chain counters nested too deeply"], [PI_CHAIN_TOO_BIG , "chain is too long"], [PI_DEPRECATED , "deprecated function removed"], + [PI_NOT_IN_SER_MODE , "gpio not opened for bit-bang serial"], + [PI_BAD_SER_INVERT , "bit-bang serial invert not 0 or 1"], ] @@ -3324,6 +3331,19 @@ class pi(): """ return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRC, user_gpio, 0)) + def bb_serial_invert(self, user_gpio, invert): + """ + Invert serial logic. + + user_gpio:= 0-31 (opened in a prior call to [*bb_serial_read_open*]) + invert:= 0-1 (1 invert, 0 normal) + + ... + status = pi.bb_serial_invert(17, 1) + ... + """ + return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRI, user_gpio, invert, 0)) + def custom_1(self, arg1=0, arg2=0, argx=[]): """ Calls a pigpio function customised by the user. @@ -3718,6 +3738,8 @@ def xref(): PI_CHAIN_NESTING = -118 PI_CHAIN_TOO_BIG = -119 PI_DEPRECATED = -120 + PI_NOT_IN_SER_MODE =-121 + PI_BAD_SER_INVERT =-122 . . frequency: 0-40000 diff --git a/pigpiod_if.3 b/pigpiod_if.3 index 592a473..fff471d 100644 --- a/pigpiod_if.3 +++ b/pigpiod_if.3 @@ -2187,6 +2187,26 @@ user_gpio: 0-31, previously opened with \fBbb_serial_read_open\fP. .br Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO. +.IP "\fBint bb_serial_invert(unsigned user_gpio, unsigned invert)\fP" +.IP "" 4 +This function inverts the serial logic for bit bang reading of serial data. + +.br + +.br + +.EX +user_gpio: 0-31, previously opened with \fBbb_serial_read_open\fP. + invert: 0-1, 1 invert , 0 normal. +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_NOT_IN_SER_MODE or PI_BAD_SER_INVERT. + .IP "\fBint i2c_open(unsigned i2c_bus, unsigned i2c_addr, unsigned i2c_flags)\fP" .IP "" 4 This returns a handle for the device at address i2c_addr on bus i2c_bus. diff --git a/pigpiod_if.c b/pigpiod_if.c index 48fa085..79a4f03 100644 --- a/pigpiod_if.c +++ b/pigpiod_if.c @@ -941,6 +941,9 @@ int bb_serial_read(unsigned user_gpio, void *buf, size_t bufSize) int bb_serial_read_close(unsigned user_gpio) {return pigpio_command(gPigCommand, PI_CMD_SLRC, user_gpio, 0, 1);} +int bb_serial_invert(unsigned user_gpio, unsigned invert) + {return pigpio_command(gPigCommand, PI_CMD_SLRI, user_gpio, invert, 1);} + int i2c_open(unsigned i2c_bus, unsigned i2c_addr, uint32_t i2c_flags) { gpioExtent_t ext[1]; diff --git a/pigpiod_if.h b/pigpiod_if.h index ae96930..ddb298f 100644 --- a/pigpiod_if.h +++ b/pigpiod_if.h @@ -161,6 +161,7 @@ notify_close Close a notification bb_serial_read_open Opens a gpio for bit bang serial reads bb_serial_read Reads bit bang serial data from a gpio bb_serial_read_close Closes a gpio for bit bang serial reads +bb_serial_invert Invert serial logic (1 invert, 0 normal) hardware_clock Start hardware clock on supported gpios hardware_PWM Start hardware PWM on supported gpios @@ -1501,6 +1502,19 @@ user_gpio: 0-31, previously opened with [*bb_serial_read_open*]. Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO. D*/ +/*F*/ +int bb_serial_invert(unsigned user_gpio, unsigned invert); +/*D +This function inverts serial logic for big bang serial reads. + +. . +user_gpio: 0-31, previously opened with [*bb_serial_read_open*]. + invert: 0-1, 1 invert, 0 normal. +. . + +Returns 0 if OK, otherwise PI_NOT_IN_SER_MODE or PI_BAD_SER_INVERT. +D*/ + /*F*/ int i2c_open(unsigned i2c_bus, unsigned i2c_addr, unsigned i2c_flags); /*D diff --git a/pigs.1 b/pigs.1 index 3dfaad7..cdaa36d 100644 --- a/pigs.1 +++ b/pigs.1 @@ -2612,6 +2612,36 @@ ERROR: gpio already in use .br +.IP "\fBSLRI u i\fP - Invert serial logic for bit bang serial data" +.IP "" 4 + +.br +This command inverts the serial logic when reading bit bang serial data. + +.br +Upon success nothing is returned. On error a negative status code +will be returned. + +.br +The invert parameter is 1 for inverted signal, 0 for normal. + +.br + +\fBExample\fP +.br + +.EX +$ pigs slri 17 1 +.br + +.br +$ pigs slri 17 0 +.br + +.EE + +.br + .IP "\fBSPIC h\fP - SPI close handle" .IP "" 4