From b99a538aeea2a1ab5d3cef5cc3279115ed936fe5 Mon Sep 17 00:00:00 2001 From: Dawid Sabat Date: Fri, 18 Sep 2020 23:28:18 +0200 Subject: [PATCH 01/19] Modify pigpio_start arguments --- pigpiod_if2.c | 4 ++-- pigpiod_if2.h | 2 +- x_pigpiod_if2.c | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pigpiod_if2.c b/pigpiod_if2.c index ab2ef10..64b0d15 100644 --- a/pigpiod_if2.c +++ b/pigpiod_if2.c @@ -234,7 +234,7 @@ static int pigpio_command_ext return cmd.res; } -static int pigpioOpenSocket(char *addrStr, char *portStr) +static int pigpioOpenSocket(const char *addrStr, const char *portStr) { int sock, err, opt; struct addrinfo hints, *res, *rp; @@ -685,7 +685,7 @@ void stop_thread(pthread_t *pth) } } -int pigpio_start(char *addrStr, char *portStr) +int pigpio_start(const char *addrStr, const char *portStr) { int pi; int *userdata; diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 9700cc0..4e3314d 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -429,7 +429,7 @@ The thread to be stopped should have been started with [*start_thread*]. D*/ /*F*/ -int pigpio_start(char *addrStr, char *portStr); +int pigpio_start(const char *addrStr, const char *portStr); /*D Connect to the pigpio daemon. Reserving command and notification streams. diff --git a/x_pigpiod_if2.c b/x_pigpiod_if2.c index c9b2c27..9422aee 100644 --- a/x_pigpiod_if2.c +++ b/x_pigpiod_if2.c @@ -77,6 +77,10 @@ void t1(int pi) gpio_write(pi, GPIO, PI_HIGH); v = gpio_read(pi, GPIO); CHECK(1, 6, v, 1, 0, "write, read"); + + v = pigpio_start(PI_DEFAULT_SOCKET_ADDR_STR, PI_DEFAULT_SOCKET_PORT_STR); + CHECK(1, 7, v, 31, 100, "pigpio_start with non-default arguments"); + pigpio_stop(v); } int t2_count=0; From 15d4193ed1613246d921e720ea14363efe0ee0bc Mon Sep 17 00:00:00 2001 From: joan2937 Date: Sun, 15 Nov 2020 16:43:36 +0000 Subject: [PATCH 02/19] bit bang example code from paulvee --- DOC/dbase/pigpio.sqlite | Bin 1433600 -> 1433600 bytes DOC/src/defs/examples.def | 6 ++++++ 2 files changed, 6 insertions(+) diff --git a/DOC/dbase/pigpio.sqlite b/DOC/dbase/pigpio.sqlite index f24fd30acb732b2cd3b9676e570ebb7a00e94642..c0b12054981475c9ba0475f082cbf3d10ad9887c 100644 GIT binary patch delta 1143 zcmbV}Ur1A77{+(b&gSN(`{Q1NbonU;UZguyupk*qN>QoHzbguNww>g}b~g6M77@&h zqeR6CqVJ{)!wbDkR(%j%NF`JdSXW(2*IjtwtTDpEOveH# zNl^niIjcy?nOJOQHk0eh+@kZS3|Ap+3&oT?iAm}#!Rz`0Qm8MM4Rwp%VrNjK(s5|G zFjSOMnWRkO>4Z%3X%Z_a$pjf09vUDyS4PG7>?iktt*n8AryDOGp@XZ}1z!1mEfx`5h19 eMHrc?^omjeQtBQ zsLyS$wli%ylE6oMuW^axHfT*p1R02;P>%bvpaBtUnRZj3pUH3z&*;>#k6Us z(?%jBk+NE=r(e zn+!PBOHZGu?9l}{)8BQ7UWQ@bql(Yu;rt;&;POl)1ka8&Dbbfy`RpkOU)eWQbJ2lh z?u*sUr3febG7N8d)VzDGxO{RUr#4?rK&J4~`u_pf)wpyC4nF*4sJ$Pv;FY$5cm;-Q z_{{u02GP~sAgZYG#XLC8KZZKK^H|j`nDD$-4UVcXe2deqBU5VLXOOK!5Z~~>H`q6L y*ST-_Umwr}Ov=wzw-r>nsm6uF@b^=c0&NX~@!P#YgL(AL_9B!&tXuB~DgF=jx|2Ns diff --git a/DOC/src/defs/examples.def b/DOC/src/defs/examples.def index 637a82b..7eedbaf 100644 --- a/DOC/src/defs/examples.def +++ b/DOC/src/defs/examples.def @@ -511,6 +511,12 @@ pip install nrf24 ?4|https://github.com/bjarne-hansen/py-nrf24|2020-04-20|NRF24 Code and example usage of the Pypi NRF24 module. Cleaned up and added support for reading from multiple pipes using open_reading_pipe(pipe, address) and open_writing_pipe(address) in order to be more "compatible" with the way NRF24 is used on Arduinos. +?4|https://github.com/paulvee/GPSDO-Monitoring/blob/main/serial_bb_gps.py|2020-10-20|bit bang GPS +Example code to build NMEA senstences from receieved bit banged serial data. + +?4|https://github.com/paulvee/GPSDO-Monitoring/blob/main/serial_bb_counter.py|2020-10-20|bit bang GPS +Example code to bit bang read GPS counter. + ?4|https://github.com/stripcode/pigpio-stepper-motor|2016-08-12|Stepper Motor Stepper motor code. From d898affb2af32be18f65a9f8f46835844b5ca209 Mon Sep 17 00:00:00 2001 From: joan2937 Date: Mon, 16 Nov 2020 11:27:11 +0000 Subject: [PATCH 03/19] Reworked paulvee example and link. --- DOC/dbase/pigpio.sqlite | Bin 1433600 -> 1433600 bytes DOC/src/defs/examples.def | 9 +++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/DOC/dbase/pigpio.sqlite b/DOC/dbase/pigpio.sqlite index c0b12054981475c9ba0475f082cbf3d10ad9887c..9f96137ee3f1e6ebbb2c2dca3b8f1def93b8f1ae 100644 GIT binary patch delta 975 zcmZ|O%}*0S6aer}Teh@7X@NjQD#J$&5lXk15EDuHis1xOkPnFpTe?D}-CcIKq$Wli zO~4?5!f2M0Arg-Ak%=@RMrzc=L_FX@6MN}jpd2_GUyI!2@Y|Vv^WK}?$!;t;6iW`p z&m;G8MJICajICF$8`E)WOCK-6rGT9?N(ktI0T@9}!YDDwmSf(~nK!7%)}v1hKW6F} zqfTdv!F?67Jz1zR41jVa*gS(A1_AX&>(yi)d;5Q#Q6pQ!kx}tkske zx5m(_*q(JanQO42C4xF;h;M0&H116ksl!AcNTb=3I88l-5;wgP;@E09OObSzu(12xv&)Cm1^x*UXg zyRsO@oPgWqKqM%Lu%7}Q#>I%B@^S-KCpi`R2>}Jmyb=ki3g%~c`9AhEuq=y38GBfm z5oxu=)GmnXBrj+7DD9LuS>bU|P{mBS$_wMX0^NAr(|xTSE2_+MVb~@dgx5QH20Y;E z2#HbL)!UE5VjvPCNnez@ovxhPlLsD^qt)IPw<2-Ee~yMsyGw}UYenWz&z*Uw#D3tR zk@`iW;YCCtRhOFRmE@P!IfG;d7LW(>K>@IWLSRc6B)dtvhLXw`VqgO6ArT*}FK61{j(#Mvq#-r(?M|NN7gotZxp?~KGd zqeXo6Sn*cAI(Brjl+S{)7%7FF6|@+B*3$xZwv2w~D_h$4Y}-}U>esv>f55BtIz2wW z$JwWNHD^!_cokol$J5oT2dninu&|DnwChUP*RQJ16(p9sJ>HP)QM6tevl^U=yTKE1 z*Scz5RW&Y%eGqfuR|U;-hy1c9?Dh4?ZLQmz<)EqsL#o!T2IXS`f1eysyH&5+ulC4` z)$sVYN4ZA{DKMBIr;Pd5EU&k2e^?8tfyKf0u4u5Os4Loki-VI+ng{kqTD)OJz5aW>=k>I1s!(RBMIVzr#9MaMAD$KndY;m zZzOI7dkf8(UPW_xBO)@#EWw=lW@=?Qb0j}?n+}8T$Z0n5nsiy=%ZymcDw0G@g$T?h z2$qT&rK0aiKMcGg_l#1MIVOx!t|=nHofx641ZIPS&O_GGXwO*bM$x zqJ{Op7Kg3S{exTsh?1)!ma>L}5UHWHY?F(=*gR#Ed3{LGd1OLnB%m}V=pt`RBN2{7 zrfO_$CU)SQxL&lKAKj5|vD;15URG+qaI1(-UldzJxSSv-j9)%9y0turisq&%L7vaP zX|rItq{xJ1`og_QL3Z6X$B7LO<3nbhq70OYEGP?EQ8uzMvo59U>o^T7CeRrAgsz|& z^bB1^Q8Ws!q*St+8^QA>^aRDxWAq3O!||kaD1*C!=j-Siyi7{fb^H;I;}4@l=pZ_P lI?;Z#5A8u6Xg6xdyodO8<2v40hfH%4%0aozG?(}L>mSMda&Q0u diff --git a/DOC/src/defs/examples.def b/DOC/src/defs/examples.def index 7eedbaf..1ead75f 100644 --- a/DOC/src/defs/examples.def +++ b/DOC/src/defs/examples.def @@ -511,11 +511,12 @@ pip install nrf24 ?4|https://github.com/bjarne-hansen/py-nrf24|2020-04-20|NRF24 Code and example usage of the Pypi NRF24 module. Cleaned up and added support for reading from multiple pipes using open_reading_pipe(pipe, address) and open_writing_pipe(address) in order to be more "compatible" with the way NRF24 is used on Arduinos. -?4|https://github.com/paulvee/GPSDO-Monitoring/blob/main/serial_bb_gps.py|2020-10-20|bit bang GPS -Example code to build NMEA senstences from receieved bit banged serial data. +?4|https://github.com/paulvee/pigpio-serial-bb-examples|2020-11-16|bit bang serial RX +Example code showing how to use the bit banged serial links. -?4|https://github.com/paulvee/GPSDO-Monitoring/blob/main/serial_bb_counter.py|2020-10-20|bit bang GPS -Example code to bit bang read GPS counter. +One example shows how to read the serial data from an Arduino based counter, that sends results every 1,000 or 10,000 seconds. + +Another example shows how to parse into sentences the NMEA stream coming from a U-Blox GPS module. ?4|https://github.com/stripcode/pigpio-stepper-motor|2016-08-12|Stepper Motor Stepper motor code. From 0daad582ac8729eded1f3a47ec5bb506d9cc823f Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 19:15:47 -0600 Subject: [PATCH 04/19] PR #404: Include stddef.h for size_t --- pigpio.h | 1 + 1 file changed, 1 insertion(+) diff --git a/pigpio.h b/pigpio.h index 2f9fc64..08aadac 100644 --- a/pigpio.h +++ b/pigpio.h @@ -27,6 +27,7 @@ For more information, please refer to #ifndef PIGPIO_H #define PIGPIO_H +#include #include #include From 3140218f56c628ab79cdc7794db1f3e6c655bd0c Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 19:41:57 -0600 Subject: [PATCH 05/19] PR#413 Update doc: return current PWM dutycycle instead of 0 --- pigpiod_if2.3 | 2 +- pigpiod_if2.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pigpiod_if2.3 b/pigpiod_if2.3 index e5c79e8..9226593 100644 --- a/pigpiod_if2.3 +++ b/pigpiod_if2.3 @@ -949,7 +949,7 @@ user_gpio: 0-31. .br .br -Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. +Returns current PWM dutycycle if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. .br diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 4e3314d..15efdb3 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -568,7 +568,8 @@ Return the PWM dutycycle in use on a GPIO. user_gpio: 0-31. . . -Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. +Returns current PWM dutycycle if OK, +otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. For normal PWM the dutycycle will be out of the defined range for the GPIO (see [*get_PWM_range*]). From 258b0345128f9081cb1dab9254275b12093e1ab4 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 19:48:49 -0600 Subject: [PATCH 06/19] PR#415 fix simple type receieve -> receive --- pigpio.h | 2 +- pigpio.py | 2 +- pigpiod_if2.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pigpio.h b/pigpio.h index 08aadac..59dc11c 100644 --- a/pigpio.h +++ b/pigpio.h @@ -3072,7 +3072,7 @@ pages 165-166 of the Broadcom peripherals document for full details. SSSSS @ number of bytes successfully copied to transmit FIFO -RRRRR @ number of bytes in receieve FIFO +RRRRR @ number of bytes in receive FIFO TTTTT @ number of bytes in transmit FIFO RB @ receive busy TE @ transmit FIFO empty diff --git a/pigpio.py b/pigpio.py index edb6734..9c9713c 100644 --- a/pigpio.py +++ b/pigpio.py @@ -3677,7 +3677,7 @@ class pi(): details. SSSSS @ number of bytes successfully copied to transmit FIFO - RRRRR @ number of bytes in receieve FIFO + RRRRR @ number of bytes in receive FIFO TTTTT @ number of bytes in transmit FIFO RB @ receive busy TE @ transmit FIFO empty diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 15efdb3..723c59d 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -3613,7 +3613,7 @@ pages 165-166 of the Broadcom peripherals document for full details. SSSSS @ number of bytes successfully copied to transmit FIFO -RRRRR @ number of bytes in receieve FIFO +RRRRR @ number of bytes in receive FIFO TTTTT @ number of bytes in transmit FIFO RB @ receive busy TE @ transmit FIFO empty From 55608548fc1badce771f9f1e4e1b69c52e914e9c Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 19:56:35 -0600 Subject: [PATCH 07/19] Fix Issue#402 Cannot handle multiple I2C devices on RPi 4B --- pigpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pigpio.c b/pigpio.c index 92b9bf7..9428b71 100644 --- a/pigpio.c +++ b/pigpio.c @@ -4116,7 +4116,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags) i2cInfo[slot].addr = i2cAddr; i2cInfo[slot].flags = i2cFlags; i2cInfo[slot].funcs = funcs; - i2cInfo[i].state = PI_I2C_OPENED; + i2cInfo[slot].state = PI_I2C_OPENED; return slot; } From 2220e497bda8b274677e660fb5922cbb31487235 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 20:23:52 -0600 Subject: [PATCH 08/19] Fix issue#397 gpioSetTimerFunc NULL cancel error --- pigpio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pigpio.c b/pigpio.c index 9428b71..af94c11 100644 --- a/pigpio.c +++ b/pigpio.c @@ -12488,8 +12488,11 @@ int gpioSetTimerFunc(unsigned id, unsigned millis, gpioTimerFunc_t f) if (id > PI_MAX_TIMER) SOFT_ERROR(PI_BAD_TIMER, "bad timer id (%d)", id); - if ((millis < PI_MIN_MS) || (millis > PI_MAX_MS)) - SOFT_ERROR(PI_BAD_MS, "timer %d, bad millis (%d)", id, millis); + if (f) + { + if ((millis < PI_MIN_MS) || (millis > PI_MAX_MS)) + SOFT_ERROR(PI_BAD_MS, "timer %d, bad millis (%d)", id, millis); + } intGpioSetTimerFunc(id, millis, f, 0, NULL); From 8f4eff969406da79f2559b2af89d8e7168cb35d7 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 20:32:16 -0600 Subject: [PATCH 09/19] Fix issue#400 PI_CMD_EVT is unused in pigpiod_if2.c --- pigpiod_if2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pigpiod_if2.c b/pigpiod_if2.c index 64b0d15..f8dc9c7 100644 --- a/pigpiod_if2.c +++ b/pigpiod_if2.c @@ -2122,5 +2122,5 @@ int wait_for_event(int pi, unsigned event, double timeout) } int event_trigger(int pi, unsigned event) - {return pigpio_command(pi, PI_CMD_EVM, event, 0, 1);} + {return pigpio_command(pi, PI_CMD_EVT, event, 0, 1);} From 1420fe1799619bb9d9bf3df0853c20f9745c71ef Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 20:39:24 -0600 Subject: [PATCH 10/19] Fix issue#405 Prototype for gpioRunScript is duplicated. --- pigpio.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/pigpio.h b/pigpio.h index 59dc11c..b5ef7e9 100644 --- a/pigpio.h +++ b/pigpio.h @@ -3863,24 +3863,6 @@ param is an array of up to 10 parameters which may be referenced in the script as p0 to p9. D*/ -/*F*/ -int gpioRunScript(unsigned script_id, unsigned numPar, uint32_t *param); -/*D -This function runs a stored script. - -. . -script_id: >=0, as returned by [*gpioStoreScript*] - numPar: 0-10, the number of parameters - param: an array of parameters -. . - -The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID, or -PI_TOO_MANY_PARAM. - -param is an array of up to 10 parameters which may be referenced in -the script as p0 to p9. -D*/ - /*F*/ From 11ee6f19d8d64f5d03587da0039dcc30c51ef2b2 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 23:09:58 -0600 Subject: [PATCH 11/19] bump develop branch version --- pigpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pigpio.h b/pigpio.h index b5ef7e9..bd5fbef 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 7800 +#define PIGPIO_VERSION 7801 /*TEXT From 35aa210556e558720ba9ab883098e284ed531c26 Mon Sep 17 00:00:00 2001 From: Mark Date: Sun, 20 Dec 2020 09:16:10 -0800 Subject: [PATCH 12/19] added an example of using the pigpio library to implement the SENT interface. SENT is an automotive standard single wire interface for robust communication with sensors in a car, but the standard can be used anywhere. It has error detection including CRC checking. There is a write up about it on the Blog: https://surfncircuits.com/2020/11/27/implementing-a-single-edge-nibble-transmission-sent-protocol-in-python-for-the-raspberry-pi-zero/ --- EXAMPLES/Python/SENT_PROTOCOL/README.md | 28 ++ EXAMPLES/Python/SENT_PROTOCOL/read_SENT.py | 322 +++++++++++++++++++++ 2 files changed, 350 insertions(+) create mode 100644 EXAMPLES/Python/SENT_PROTOCOL/README.md create mode 100644 EXAMPLES/Python/SENT_PROTOCOL/read_SENT.py diff --git a/EXAMPLES/Python/SENT_PROTOCOL/README.md b/EXAMPLES/Python/SENT_PROTOCOL/README.md new file mode 100644 index 0000000..8f3c83b --- /dev/null +++ b/EXAMPLES/Python/SENT_PROTOCOL/README.md @@ -0,0 +1,28 @@ +# Python Class for Reading Single Edge Nibble Transmission (SENT) using the Raspberry Pi + +A full description of this Python script is described at [www.surfncircuits.com](https://surfncircuits.com) in the blog entry: [Implementing a Single Edge Nibble Transmission (SENT) protocol in Python for the Raspberry Pi Zero](https://surfncircuits.com/?p=3725) + + +This python library will read a Raspberry Pi GPIO pin connected. Start the pigpiod daemon with one microsecond sampling to read SENT transmissions with three microsecond tick times. + +## To start the daemon on Raspberry Pi +- sudo pigpiod -s 1 + +## SENT packet frame summary + +- Sync Pulse: 56 ticks +- 4 bit Status and Message Pulse: 17-32 ticks +- 4 bit (9:12) Data1 Field: 17-32 ticks +- 4 bit (5:8) Data1 Field: 17-32 ticks +- 4 bit (1:4) Data1 Field: 17-32 ticks +- 4 bit (9-12) Data2 Field: 17-32 ticks +- 4 bit (5-8) Data2 Field: 17-32 ticks +- 4 bit (1-4) Data2 Field: 17-32 ticks +- 4 bit CRC: 17-32 ticks + + +## requirements +[pigpiod](http://abyz.me.uk/rpi/pigpio/) library required + +## To run the script for a signal attached to GPIO BCD 18 (pin 12) +- python3 sent_READ.py diff --git a/EXAMPLES/Python/SENT_PROTOCOL/read_SENT.py b/EXAMPLES/Python/SENT_PROTOCOL/read_SENT.py new file mode 100644 index 0000000..1bc9709 --- /dev/null +++ b/EXAMPLES/Python/SENT_PROTOCOL/read_SENT.py @@ -0,0 +1,322 @@ +#!/usr/bin/env python3 + +# read_PWM.py +# Public Domain by mark smith, www.surfncircuits.com +# blog:https://surfncircuits.com/2020/11/27/implementing-a-single-edge-nibble-transmission-sent-protocol-in-python-for-the-raspberry-pi-zero/ + +import time +import pigpio # http://abyz.co.uk/rpi/pigpio/python.html +import threading + +class SENTReader: + """ + A class to read short Format SENT frames + (see the LX3302A datasheet for a SENT reference from Microchip) + (also using sent transmission mode where ) + from wikiPedia: The SAE J2716 SENT (Single Edge Nibble Transmission) protocol + is a point-to-point scheme for transmitting signal values + from a sensor to a controller. It is intended to allow for + transmission of high resolution data with a low system cost. + + Short sensor format: + The first is the SYNC pulse (56 ticks) + first Nibble : Status (4 bits) + 2nd NIbble : DAta1 (4 bits) + 3nd Nibble : Data2 (4 bits) + 4th Nibble : Data3 (4 bits) + 5th Nibble : Data1 (4 bits) + 6th Nibble : Data2 (4 bits) + 7th Nibble : Data3 (4 bits) + 8th Nibble : CRC (4 bits) + """ + def __init__(self, pi, gpio, Mode = 0): + """ + Instantiate with the Pi and gpio of the SENT signal + to monitor. + SENT mode = A0: Microchip LX3302A where the two 12 bit data values are identical. there are other modes + + """ + self.pi = pi + self.gpio = gpio + self.SENTMode = Mode + + # the time that pulse goes high + self._high_tick = 0 + # the period of the low tick + self._low_tick = 0 + # the period of the pulse (total data) + self._period = 0 + # the time the item was low during the period + self._low = 0 + # the time the output was high during the period + self._high = 0 + # setting initial value to 100 + self.syncTick = 100 + + + #keep track of the periods + self.syncWidth = 0 + self.status = 0 + self.data1 = 0 + self.data2 = 0 + self.data3 = 0 + self.data4 = 0 + self.data5 = 0 + self.data6 = 0 + self.crc = 0 + #initize the sent frame . Need to use hex for data + #self.frame = [0,0,0,'0x0','0x0','0x0','0x0','0x0','0x0',0] + self.frame = [0,0,0,0,0,0,0,0,0,0] + self.syncFound = False + self.frameComplete = False + self.nibble = 0 + self.numberFrames = 0 + self.SampleStopped = False + + self.pi.set_mode(gpio, pigpio.INPUT) + + #self._cb = pi.callback(gpio, pigpio.EITHER_EDGE, self._cbf) + #sleep enougth to start reading SENT + #time.sleep(0.05) + + #start thread to sample the SENT property + # this is needed for piGPIO sample of 1us and sensing the 3us + self.OutputSampleThread = threading.Thread(target = self.SampleCallBack) + self.OutputSampleThread.daemon = True + self.OutputSampleThread.start() + + #give time for thread to start capturing data + time.sleep(.05) + + + def SampleCallBack(self): + + # this will run in a loop and sample the SENT path + # this sampling is required when 1us sample rate for SENT 3us tick time + while True: + + self.SampleStopped = False + self._cb = self.pi.callback(self.gpio, pigpio.EITHER_EDGE, self._cbf) + # wait until sample stopped + while self.SampleStopped == False: + #do nothing + time.sleep(.001) + + # gives the callback time to cancel so we can start again. + time.sleep(0.20) + + def _cbf(self, gpio, level, tick): + # depending on the system state set the tick times. + # first look for sync pulse. this is found when duty ratio >90 + #print(pgio) + #print("inside _cpf") + #print(tick) + if self.syncFound == False: + if level == 1: + self._high_tick = tick + self._low = pigpio.tickDiff(self._low_tick,tick) + elif level == 0: + # this may be a syncpulse if the duty is 51/56 + self._period = pigpio.tickDiff(self._low_tick,tick) + # not reset the self._low_tick + self._low_tick = tick + self._high = pigpio.tickDiff(self._high_tick,tick) + # sync pulse is detected by finding duty ratio. 51/56 + # but also filter if period is > 90us*56 = 5040 + if (100*self._high/self._period) > 87 and (self._period<5100): + self.syncFound = True + self.syncWidth = self._high + self.syncPeriod = self._period + #self.syncTick = round(self.syncPeriod/56.0,2) + self.syncTick = self.syncPeriod + # reset the nibble to zero + self.nibble = 0 + self.SampleStopped = False + else: + # now look for the nibble information for each nibble (8 Nibbles) + if level == 1: + self._high_tick = tick + self._low = pigpio.tickDiff(self._low_tick,tick) + elif level == 0: + # This will be a data nibble + self._period = pigpio.tickDiff(self._low_tick,tick) + # not reset the self._low_tick + self._low_tick = tick + self._high = pigpio.tickDiff(self._high_tick,tick) + self.nibble = self.nibble + 1 + if self.nibble == 1: + self.status = self._period + elif self.nibble == 2: + #self.data1 = hex(int(round(self._period / self.syncTick)-12)) + self.data1 = self._period + elif self.nibble == 3: + self.data2 = self._period + elif self.nibble == 4: + self.data3 = self._period + elif self.nibble == 5: + self.data4 = self._period + elif self.nibble == 6: + self.data5 = self._period + elif self.nibble == 7: + self.data6 = self._period + elif self.nibble == 8: + self.crc = self._period + # now send all to the SENT Frame + self.frame = [self.syncPeriod,self.syncTick,self.status,self.data1,self.data2,self.data3,self.data4,self.data5,self.data6,self.crc] + self.syncFound = False + self.nibble = 0 + self.numberFrames += 1 + if self.numberFrames > 2: + self.cancel() + self.SampleStopped = True + self.numberFrames = 0 + + def ConvertData(self,tickdata,tickTime): + if tickdata == 0: + t = '0x0' + else: + t = hex(int(round(tickdata / tickTime)-12)) + if t[0] =='-': + t='0x0' + return t + + def SENTData(self): + # check that data1 = Data2 if they are not equal return fault = True + # will check the CRC code for faults. if fault, return = true + # returns status, data1, data2, crc, fault + #self._cb = self.pi.callback(self.gpio, pigpio.EITHER_EDGE, self._cbf) + #time.sleep(0.1) + fault = False + SentFrame = self.frame[:] + SENTTick = round(SentFrame[1]/56.0,2) + + # the greatest SYNC sync is 90us. So trip a fault if this occurs + if SENTTick > 90: + fault = True + + #print(SentFrame) + # convert SentFrame to HEX Format including the status and Crc bits + for x in range (2,10): + SentFrame[x] = self.ConvertData(SentFrame[x],SENTTick) + SENTCrc = SentFrame[9] + SENTStatus = SentFrame[2] + SENTPeriod = SentFrame[0] + #print(SentFrame) + # combine the datafield nibbles + datanibble = '0x' + datanibble2 = '0x' + for x in range (3,6): + datanibble = datanibble + str((SentFrame[x]))[2:] + for x in range (6,9): + datanibble2 = datanibble2 + str((SentFrame[x]))[2:] + # if using SENT mode 0, then data nibbles should be equal + #if self.SENTMode == 0 : + # if datanibble != datanibble2: + # fault = True + # if datanibble or datanibble2 == 0 then fault = true + if (int(datanibble,16) == 0) or (int(datanibble2,16) ==0): + fault = True + # if datanibble or datanibble2 > FFF (4096) then fault = True + if ( (int(datanibble,16) > 0xFFF) or (int(datanibble2,16) > 0xFFF)): + fault = True + #print(datanibble) + # CRC checking + # converting the datanibble values to a binary bit string. + # remove the first two characters. Not needed for crcCheck + InputBitString = bin(int((datanibble + datanibble2[2:]),16))[2:] + # converting Crcvalue to bin but remove the first two characters 0b + # format is set to remove the leading 0b, 4 charactors long + crcBitValue = format(int(str(SENTCrc),16),'04b') + #checking the crcValue + # polybitstring is 1*X^4+1*X^3+1*x^2+0*X+1 = '11101' + if self.crcCheck(InputBitString,'11101',crcBitValue) == False: + fault = True + + # converter to decimnal + returnData = int(datanibble,16) + returnData2 = int(datanibble2,16) + #returns both Data values and if there is a FAULT + return (SENTStatus, returnData, returnData2,SENTTick, SENTCrc, fault, SENTPeriod) + + def tick(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return ticktime + + def crcNibble(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return crc + + def dataField1(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return data1 + + def dataField2(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return data2 + + def statusNibble(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return status + + def syncPulse(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return syncPulse + + def errorFrame(self): + status, data1, data2, ticktime, crc, errors, syncPulse = self.SENTData() + return errors + + def cancel(self): + self._cb.cancel() + + def stop(self): + self.OutputSampleThread.stop() + + def crcCheck(self, InputBitString, PolyBitString, crcValue ): + # the input string will be a binary string all 6 nibbles of the SENT data + # the seed value ( = '0101) is appended to the input string. Do not use zeros for SENT protocal + # this uses the SENT CRC recommended implementation. + checkOK = False + + LenPolyBitString = len(PolyBitString) + PolyBitString = PolyBitString.lstrip('0') + LenInput = len(InputBitString) + InputPaddedArray = list(InputBitString + '0101') + while '1' in InputPaddedArray[:LenInput]: + cur_shift = InputPaddedArray.index('1') + for i in range(len(PolyBitString)): + InputPaddedArray[cur_shift + i] = str(int(PolyBitString[i] != InputPaddedArray[cur_shift + i])) + + if (InputPaddedArray[LenInput:] == list(crcValue)): + checkOK = True + + return checkOK + +if __name__ == "__main__": + + import time + import pigpio + import read_SENT + + SENT_GPIO = 18 + RUN_TIME = 6000000000.0 + SAMPLE_TIME = 0.1 + + pi = pigpio.pi() + + p = read_SENT.SENTReader(pi, SENT_GPIO) + + start = time.time() + + while (time.time() - start) < RUN_TIME: + + time.sleep(SAMPLE_TIME) + + status, data1, data2, ticktime, crc, errors, syncPulse = p.SENTData() + print("Sent Status= %s - 12-bit DATA 1= %4.0f - DATA 2= %4.0f - tickTime(uS)= %4.2f - CRC= %s - Errors= %s - PERIOD = %s" % (status,data1,data2,ticktime,crc,errors,syncPulse)) + print("Sent Stat2s= %s - 12-bit DATA 1= %4.0f - DATA 2= %4.0f - tickTime(uS)= %4.2f - CRC= %s - Errors= %s - PERIOD = %s" % (p.statusNibble(),p.dataField1(),p.dataField2(),p.tick(),p.crcNibble(),p.errorFrame(),p.syncPulse())) + + # stop the thread in SENTReader + p.stop() + # clear the pi object instance + pi.stop() From f51cd7e950c08c7460fda84372a2d6552416762b Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Wed, 23 Dec 2020 23:08:11 -0600 Subject: [PATCH 13/19] 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*/ From 7baf4a6467a1a05396f3028d80d06f7b86c02a0e Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Wed, 23 Dec 2020 23:11:15 -0600 Subject: [PATCH 14/19] Auto generate MAN and HTML. --- DOC/dbase/pigpio.sqlite | Bin 1433600 -> 1433600 bytes pigpio.3 | 59 ++++++++++++++-------------------------- pigpiod_if2.3 | 34 +++++++++++++++-------- pigs.1 | 59 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 96 insertions(+), 56 deletions(-) diff --git a/DOC/dbase/pigpio.sqlite b/DOC/dbase/pigpio.sqlite index 9f96137ee3f1e6ebbb2c2dca3b8f1def93b8f1ae..017dd86e9dca6cf22b79549b8ae3aaa0353a0618 100644 GIT binary patch delta 11560 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 UG_hOhO^4u(EPcDuz&@h=H_nsEwEzGB delta 8068 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 ywWZLO3= 0) .EE +.br + +.br +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. + +.br + +.br +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. + .IP "\fBint bbSPIOpen(unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK, unsigned baud, unsigned spiFlags)\fP" .IP "" 4 This function selects a set of GPIO for bit banging SPI with @@ -5908,36 +5919,6 @@ PI_TOO_MANY_PARAM. param is an array of up to 10 parameters which may be referenced in the script as p0 to p9. -.IP "\fBint gpioRunScript(unsigned script_id, unsigned numPar, uint32_t *param)\fP" -.IP "" 4 -This function runs a stored script. - -.br - -.br - -.EX -script_id: >=0, as returned by \fBgpioStoreScript\fP -.br - numPar: 0-10, the number of parameters -.br - param: an array of parameters -.br - -.EE - -.br - -.br -The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID, or -PI_TOO_MANY_PARAM. - -.br - -.br -param is an array of up to 10 parameters which may be referenced in -the script as p0 to p9. - .IP "\fBint gpioUpdateScript(unsigned script_id, unsigned numPar, uint32_t *param)\fP" .IP "" 4 This function sets the parameters of a script. The script may or diff --git a/pigpiod_if2.3 b/pigpiod_if2.3 index 9226593..1f55ee5 100644 --- a/pigpiod_if2.3 +++ b/pigpiod_if2.3 @@ -716,7 +716,7 @@ No value is returned. .br The thread to be stopped should have been started with \fBstart_thread\fP. -.IP "\fBint pigpio_start(char *addrStr, char *portStr)\fP" +.IP "\fBint pigpio_start(const char *addrStr, const char *portStr)\fP" .IP "" 4 Connect to the pigpio daemon. Reserving command and notification streams. @@ -949,7 +949,8 @@ user_gpio: 0-31. .br .br -Returns current PWM dutycycle if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. +Returns current PWM dutycycle if OK, +otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. .br @@ -6215,12 +6216,6 @@ queue and the master removes it. .br -.br -I can't get SPI to work properly. I tried with a -control word of 0x303 and swapped MISO and MOSI. - -.br - .br The function sets the BSC mode, writes any data in the transmit buffer to the BSC transmit FIFO, and @@ -6306,7 +6301,7 @@ GPIO used for models other than those based on the BCM2711. .br I2C 18 19 - - - - .br -SPI - - 18 19 20 21 +SPI - - 20 19 18 21 .br .br @@ -6321,7 +6316,7 @@ GPIO used for models based on the BCM2711 (e.g. the Pi4B). .br I2C 10 11 - - - - .br -SPI - - 10 11 9 8 +SPI - - 9 11 10 8 .br .br @@ -6417,7 +6412,7 @@ details. .br SSSSS number of bytes successfully copied to transmit FIFO .br -RRRRR number of bytes in receieve FIFO +RRRRR number of bytes in receive FIFO .br TTTTT number of bytes in transmit FIFO .br @@ -6476,6 +6471,23 @@ if (status >= 0) .EE +.br + +.br +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. + +.br + +.br +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. + .IP "\fBint bsc_i2c(int pi, int i2c_addr, bsc_xfer_t *bscxfer)\fP" .IP "" 4 This function allows the Pi to act as a slave I2C device. diff --git a/pigs.1 b/pigs.1 index 9b53e0e..1d9bf6f 100644 --- a/pigs.1 +++ b/pigs.1 @@ -928,10 +928,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. -.br -I can't get SPI to work properly. I tried with a -control word of 0x303 and swapped MISO and MOSI. - .br The command sets the BSC mode and writes any data \fBbvs\fP to the BSC transmit FIFO. It returns the data count (at least 1 @@ -956,7 +952,7 @@ GPIO used for models other than those based on the BCM2711. .EX SDA SCL MOSI SCLK MISO CE I2C 18 19 - - - - -SPI - - 18 19 20 21 +SPI - - 20 19 18 21 .EE @@ -968,7 +964,7 @@ GPIO used for models based on the BCM2711 (e.g. the Pi4B). .EX SDA SCL MOSI SCLK MISO CE I2C 10 11 - - - - -SPI - - 10 11 9 8 +SPI - - 9 11 10 8 .EE @@ -1139,6 +1135,57 @@ $ pigs i2crd 0 5 .EE +.br +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. + +.br +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. + +.br +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). + +.br + +\fBExample\fP +.br + +.EX +$ pigs bspio 15 26 13 14 10000 0 # open bit-bang spi master on random gpio +.br + +.br +$ pigs bscx 0x303 # start BSC as SPI slave, both rx and tx enabled +.br +1 18 +.br + +.br +$ pigs bspix 15 0 0xd 0xe 0xa 0xd # write 0xdead to BSC +.br +5 0 0 0 0 0 +.br + +.br +$ pigs bscx 0x303 0xb 0xe 0xe 0xf # place 0xbeef in BSC tx FIFO, read rx FIFO +.br +5 262338 13 14 10 13 +.br + +.br +$ pigs bspix 15 1 0 0 0 0 # read four bytes from BSC +.br +5 0 11 14 14 15 +.br + +.EE + .br .IP "\fBBSPIC cs\fP - Close bit bang SPI" From 0f2927b727ae88ce8074dba72c07b4943e9e1803 Mon Sep 17 00:00:00 2001 From: joan2937 Date: Sun, 3 Jan 2021 11:29:32 +0000 Subject: [PATCH 15/19] Added docker link to other languages section of index.html (main page). --- DOC/src/html/index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DOC/src/html/index.html b/DOC/src/html/index.html index 0b8e33c..4687093 100644 --- a/DOC/src/html/index.html +++ b/DOC/src/html/index.html @@ -622,6 +622,10 @@ Languages for pigpio.

Some are listed here:

    + +
  • Docker +Note that pigpio does not support or accept issues relating to problems of running in docker. Use the docker projects own issue tracker for that (zinen)
  • +
  • Erlang (skvamme)
  • Java JNI From 3c972b8cdb63f62662c49782e08a3a14609e75a5 Mon Sep 17 00:00:00 2001 From: joan2937 Date: Sun, 3 Jan 2021 16:15:00 +0000 Subject: [PATCH 16/19] Added "forth" link to other languages section of index.html (main page). --- DOC/src/html/index.html | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/DOC/src/html/index.html b/DOC/src/html/index.html index 4687093..b607206 100644 --- a/DOC/src/html/index.html +++ b/DOC/src/html/index.html @@ -626,33 +626,46 @@ for pigpio.

  • Docker Note that pigpio does not support or accept issues relating to problems of running in docker. Use the docker projects own issue tracker for that (zinen)
  • -
  • Erlang -(skvamme)
  • +
  • Erlang(skvamme)
  • + +
  • Forth(skvamme)
  • +
  • Java JNI wrapper around the pigpio C library (mattlewis)
  • +
  • Java via diozero, a high level wrapper around pigpio, Pi4J, wiringPi etc (mattlewis)
  • +
  • Java (nkolban)
  • +
  • .NET/mono (unosquare)
  • +
  • Node.js A wrapper for the pigpio C library (fivdi)
  • +
  • Node.js A client for pigpio socket interface (guymcswain)
  • +
  • Perl (Gligan Calin Horea)
  • +
  • Ruby (Nak)
  • +
  • Smalltalk(Instantiations)
  • +
  • Xojo(UBogun)
  • +
  • Xojo(Eugene Dakin)
  • +

The PWM and servo pulses are timed using the DMA From d1afccf04fc14df778df9287fd379c0c41f5261c Mon Sep 17 00:00:00 2001 From: Peter Michael Green Date: Thu, 28 Jan 2021 20:18:56 +0000 Subject: [PATCH 17/19] Fix detection of whether or not the system is a raspberry pi. --- pigpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pigpio.c b/pigpio.c index da42bfa..6c57f7d 100644 --- a/pigpio.c +++ b/pigpio.c @@ -13772,7 +13772,7 @@ unsigned gpioHardwareRevision(void) if ((rev & 0x800000) == 0) /* old rev code */ { - if (rev < 0x0016) /* all BCM2835 */ + if ((rev > 0) && (rev < 0x0016)) /* all BCM2835 */ { pi_ispi = 1; piCores = 1; From 2484b217d7919ef2c0c9ce3fb0a44ffb88206612 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Fri, 18 Dec 2020 10:16:08 -0600 Subject: [PATCH 18/19] Update README.md Removed pi4b experimental statement. --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 8727e74..e326fca 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,6 @@ pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO). -**At the moment pigpio on the Pi4B is experimental. I am not sure if the DMA channels - being used are safe. The Pi4B defaults are primary channel 7, secondary channel 6. - If these channels do not work you will have to experiment. You can set the channels - used by the pigpio daemon by invoking it with the -d and -e options, e.g. - sudo pigpiod -d 5 -e 8 to specify primary 5, secondary 8.** - ## Features * Sampling and time-stamping of GPIO 0-31 between 100,000 and 1,000,000 times per second From accd69d2fdd3404a0c56416912d87b2619d58563 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Tue, 2 Mar 2021 11:43:38 -0600 Subject: [PATCH 19/19] Bump version to 79 --- pigpio.c | 2 +- pigpio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pigpio.c b/pigpio.c index 6c57f7d..97bfc54 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 7802 */ +/* pigpio version 79 */ /* include ------------------------------------------------------- */ diff --git a/pigpio.h b/pigpio.h index 9b82271..1b8e51c 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 7802 +#define PIGPIO_VERSION 79 /*TEXT