User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

[SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Tue Apr 07, 2020 8:10 am

I verified that my 100Msps logic analyzer works on GPIO18 (can see PWM with "pigs p 18 192").

I compiled this pigpio example:
Nanosecond Pulse Generation 2014-01-29
This C program uses the PWM peripheral to generate precisely timed pulses of very short duration. Pulses as short as 4 nano seconds can be generated.

Running this takes some time because of the large gaps, but shows always high on GPIO18:

Code: Select all

pi@raspberrypi4B:~ $ sudo ./nanopulse 200 100 20000000 -lpigpio
100 pulses of 200 nanos with gap of 20000000 nanos (div=2 bits=50)
pi@raspberrypi4B:~ $ 
Should that example work on Raspbian Buster?

P.S:
Does not work on Pi3B+ with Buster.

P.P.S:
Does not work on Pi2B with Stretch:

Code: Select all

pi@raspberrypi2B:~ $ sudo ./nanopulse 100 200 200000
200 pulses of 100 nanos with gap of 200000 nanos (div=2 bits=25)
pi@raspberrypi2B:~ $ grep VERSION= /etc/os-release 
VERSION="9 (stretch)"
pi@raspberrypi2B:~ $ 
Attachments
20200407_101829.20%.jpg
20200407_101829.20%.jpg
20200407_101829.20%.jpg (249.95 KiB) Viewed 5928 times
Last edited by HermannSW on Thu Apr 09, 2020 6:47 pm, edited 1 time in total.
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

LdB
Posts: 1706
Joined: Wed Dec 07, 2016 2:29 pm

Re: pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Wed Apr 08, 2020 4:26 am

These addresses are wrong for a Pi4 that is Pi1 addresses

Code: Select all

#define CLK_BASE  0x20101000
#define GPIO_BASE 0x20200000
#define PWM_BASE  0x2020C000
Off the top of my head

Code: Select all

#define CLK_BASE  0xFE101000
#define GPIO_BASE 0xFE200000
#define PWM_BASE  0xFE20C000
I suspect the pulse will be wrong as the clock is now 54Mhz not 19.2Mhz

It's probably more desirable to make it work for all versions of Pi by just getting the Pi Base address from BCM_Host make sure to #include <bcm_host.h>

Code: Select all

PI_BASE_ADDR = bcm_host_get_peripheral_address();
GPIO_BASE	= (PI_BASE_ADDR + 0x200000);
PWM_BASE	= (PI_BASE_ADDR + 0x20C000);
CLK_BASE	= (PI_BASE_ADDR + 0x101000);
That should then work on Pi1,2,3 but delay will be wrong on Pi4 guessing 2.8 times shorter.

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

[SOLVED] Re: pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Thu Apr 09, 2020 3:24 pm

Thank you Ldb!

You are right, and official documentation does state that as well -- perhaps 2014 when Joan did write the code only Pi1 was available:
https://www.raspberrypi.org/documentati ... dresses.md
Note: please use these functions rather than hardcoded values, as this will ensure future compatibility.

This is the diff I made, updated comment on how to compile as well:

Code: Select all

$ diff nanopulse.c.orig nanopulse.c
4c4
< gcc -o nanopulse nanopulse.c
---
> gcc -I/opt/vc/include -L/opt/vc/lib -lbcm_host -o nanopulse nanopulse.c
21,23c21,25
< #define CLK_BASE  0x20101000
< #define GPIO_BASE 0x20200000
< #define PWM_BASE  0x2020C000
---
> #include <bcm_host.h> 
> #define PI_BASE_ADDR  bcm_host_get_peripheral_address()
> #define GPIO_BASE     (PI_BASE_ADDR + 0x200000)
> #define PWM_BASE      (PI_BASE_ADDR + 0x20C000)
> #define CLK_BASE      (PI_BASE_ADDR + 0x101000)
$

I tested on Pi3B+ and pulse width is correct up to measurement precision of my 100Msps logic analyzer.
10000 shows 10µs on logic analyzer, 1000 shows 1.02µs, 100 shows 0.13µs.
Now it is a good time to install the software for my 400Msps logic analyzer.
That has additional advantage of better probe cables, and a separate GND line for each channel line.

Here is an export of 7 pulses with nanos=25 and with nanos=30.
nanos.png
nanos.png
nanos.png (14.83 KiB) Viewed 5839 times
Only gap is poor, with gap=1,000,000 it should be 1ms, but it is 1.148ms.
Perhaps mynanosleep() needs to be implemented differently:

Code: Select all

static void mynanosleep(unsigned nanos)
{
   struct timespec ts, tr;

   ts.tv_sec = 0;
   ts.tv_nsec = nanos;
   while (nanosleep(&ts, &tr))
   {
      ts = tr;
   }
}
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Thu Apr 09, 2020 7:40 pm

LdB wrote:
Wed Apr 08, 2020 4:26 am
That should then work on Pi1,2,3 but delay will be wrong on Pi4 guessing 2.8 times shorter.
I just tested with only 100Msps logic analyzer on Pi2B and Pi4B -- only 1.5 times shorter on Pi4B:
Pulse lengths measured for Pi2B/Pi4B for nanos=10000/1000/100 are:
10µs/6.67µs
1µs/0.68µs
0.12µs/90ns

The values for 100 are bad for both PIs, time to install 400Msps logic analyzer software.
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Thu Apr 09, 2020 10:56 pm

I got the DSLogic logic analyzer software built/installed, and this was the first time I did that under Raspbian:
https://github.com/DreamSourceLab/DSVie ... er/INSTALL

The 3rd compilation (in DSView folder) took 28 minutes to compile on my 4GB Pi4B.
DSView did not like my two X11 displays setup (with additional 26$ 9" HDMI display), no problems after going back to one display.

I got my 400Msps logic analyzer as Christmas 2016 present, and was able to see 2.5ns resolution with Ubuntu DSView at that time:
viewtopic.php?p=1087893#p1087893

Currently I can capture view, zoom -- but I can maximally select 100MHz -- will have to read the handbook.
Top left you see ssh session on Pi3B+ with 80% duty cycle 25MHz PWM on GPIO18 via pigpio pigs command.
Bottom left you see terminal where DSView was started in.
Right you see DSView, showing 75% (only) duty cycle for 25MHz PWM.
1360x768 screenshot:
Image
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Fri Apr 10, 2020 6:22 pm

Wow -- learned a lot, and verified that "nanopulse.c" with the simple correction posted can produce single digit nanosecond pulses!

First after RTFM I learned that I need to bring DSLogic logic analyzer into "Buffer mode" in order to be able to capture withh 400MHz.
In buffer mode all is captured to logic analyzer internal memory first, and after capture completed, the data is sent via USB:
https://www.dreamsourcelab.com/doc/DSVi ... 187%2C0%5D

Logic analyzer ram size is fixed, capturing 4 channels at 400MHz allows for maximal 167.77ms to be captured.
Capturing only one channel at 400MHz allows for 671.09ms to be captured.

Next it is difficult to trigger the "nanopulse.c" generated pulses in the recorded time frame.
After RTFM I learned about trigger mode, and that saved my day.
I did set channel 0 trigger to rising edge and clicked on "Start".
Pi4B DSView did start, and then showed message "waiting for trigger".
Then I clicked into ssh session on Raspberry Pi3B+ and executed nanopulse C command.
On 1st pulse rising edge the logic analyzer started the capturing -- wonderful.

You can buy DSLogic 400Msps logic analyzer for 62$ with free shipping (same price as 3.5 years ago) -- and use it with Pi or laptop:
https://www.aliexpress.com/wholesale?tr ... t=1&page=1

400MHz capturing time scale ticks are 2.5ns apart -- light only travels 75cm(!!) in that time.
The (nanopulse.c generated) measured pulse lengths are precise up to the previous or next such tick!!

These are the values measured for 7ns..11ns range pulse widths, with 11ns measured twice -- as can be seen in animation:

Code: Select all

[ns]   [ns]
   7:    5
   8:   10
   9:  7.5
  10: 12.5
  11:   10
  11: 12.5
-
nanopulse.anim.gif
nanopulse.anim.gif
nanopulse.anim.gif (210.88 KiB) Viewed 5727 times
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Tue Oct 20, 2020 2:56 am

pigpio library allows to create 80Hz PWM with very short duty cycle low pulses (HQ camera uses 40ns signals for XVS multiple camera synchronization):
viewtopic.php?f=43&t=281913&p=1742661#p1740417

Code: Select all

pi@raspberrypi4B2:~ $ sudo pigpiod
pi@raspberrypi4B2:~ $ pigs hp 12 80 999997
pi@raspberrypi4B2:~ $ 
Image


I used nanopulse.c to create a single such pulse (of 39ns). But that pulse is high, and I needed it low. Therefore I used 74HC04N inverter IC to negate the nanopulse.c single pulse (for triggering HQ camera frame capture at arbitrary point in time, allowing for eg. 5:12 minute long exposure).
viewtopic.php?f=43&t=273358&p=1744916#p1744900
Image


That sulution needs a voltage divider anyway to go from Pi 3.3V to HQ camera XVS pin 1.8V, so having 74HC04N in the game is no big deal:
Image



Question:
How does nanopulse.c need to be modified to deliver nonosecond long low pulse(s)?
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Sat Jan 09, 2021 10:43 pm

I got a nice Christmas present, 110MHz bandwidth 2CH oszilloscope with 1GSa/s real-time sampling rate:
viewtopic.php?f=63&t=157907#p1786647

Today I asked myself how the pulses generated by nanopulse.c would look like.
I created screenshots from oscilloscope for 18..30 nanoseconds in 3ns steps.
In order to see pulses long enough, I created 100,000 pulses.
After conversion of the captured .bmp files to .png:

Code: Select all

$ for f in *.bmp; do bmptopnm $f | pnmtopng > $f.png; done
I used gimp to add circles where I think rising and falling starts, 18..30 ns apart.
Finally I used "togg" and "pngs2anim" tools to create 1fps animated .gif:
viewtopic.php?f=43&t=288576
x.anim.gif
x.anim.gif
x.anim.gif (159.57 KiB) Viewed 4784 times
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
bleep42
Posts: 259
Joined: Wed Mar 07, 2012 12:43 pm
Location: Sussex

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Fri Feb 12, 2021 8:04 pm

Hi Hermann,
I found your post above about compiling DSView, I had compiled it on an old x86 laptop, because I have 'Upgraded' my basic to a Plus and have to make a change to the code for it to be recognised, so I tried on my P4 2Gb worked fine as you say, so I can now use my Pi to compile code for my new Pico and analyse the outputs using DSView. :-) Thanks for the tip.
Regards, Kevin.

User avatar
bleep42
Posts: 259
Joined: Wed Mar 07, 2012 12:43 pm
Location: Sussex

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Sat Feb 27, 2021 4:27 pm

Hi Hermann,

Are you able to get RLE compression working on your Pi compiled DSView. When I turn it on the drop down for the sample period actually gets less, on the version I have on my PC it gets significantly longer?
For example sampling a single channel:-
with RLE enabled, 50MHz sample rate I can sample for a max of 2 seconds.
With RLE disabled, 50MHz sample rate I can sample for a max of 5.37 seconds?
RLE is supposed to compress the data so that you can store more in the internal memory, on the version on my PC it does, on the pi, it appears to get less! Any ideas?

Regards, Kevin.

User avatar
HermannSW
Posts: 6328
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Mon Mar 01, 2021 1:50 am

Hi Kevin,

I just tried with my 16CH 400Msps logic analyzer.
When I enable 3 channels for capturing in buffered mode at 400MHz, I get 223ms without RLE, 250ms with RLE.
When I capture only one channel I get 250ms with RLE enabled, but 671.09ms with RLE disabled.

I know that I nearly always captured in buffered mode.
And most times with maximal 3 channels.
And that my maximal capture time was 250ms.
So I seem to have had RLE enabled during all my measurements in the past.
DSView.RLE.png
DSView.RLE.png
DSView.RLE.png (44.26 KiB) Viewed 4301 times
https://github.com/Hermann-SW/RSA_numbers_factored
https://stamm-wilbrandt.de/GS [304+402+536fps]
https://hermann-sw.github.io/planar_graph_playground
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de

User avatar
bleep42
Posts: 259
Joined: Wed Mar 07, 2012 12:43 pm
Location: Sussex

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Mon Mar 01, 2021 10:45 am

Hi Hermann,
Yes that's exactly what I'm getting, so RLE isn't working properly :-(
On My WinDoze PC @400Mhz sample rate I get 671.09ms with RLE disabled and all the way up to 42.9sec with RLE enabled, though that will very much depend on the repetitiveness of the signal, in the past when I've used it on a highly active signal, I would only get say 4s when the selected drop down was 5s, but still an large increase on recording raw.
I have got an x86 Ubuntu laptop, for which I compiled the source, I'll give that a try as a comparison.
Regards, Kevin.
Edit1: The x86 Ubuntu laptop works the same as my WinDoze PC, so it is some sort of compiler problem on the Pi.
Edit2: I've now recompiled, but using 10.2.0 C compiler, exactly the same result RLE not functioning correctly on Pi. :-(

User avatar
bleep42
Posts: 259
Joined: Wed Mar 07, 2012 12:43 pm
Location: Sussex

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Mon Mar 08, 2021 1:11 pm

Hi Hermann,
Ok I've fixed it, it was an error on the source code, they had a #if define for x86 and x64, but not ARM, as soon as I added it and recompiled, I'm now getting the full use of the RLE compression, if you want it.
modify file where you extracted the tar DSView-1.12/DSView/pv/toolbars/samplingbar.cpp
at lines 555 and 557 change the code to the following.

Code: Select all

    if (dev_inst->dev_inst()->mode == LOGIC) {
        #if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__)
            sw_depth = LogicMaxSWDepth64;
        #elif defined(__i386) || defined(_M_IX86) || defined(__arm__) || defined(_M_ARM)
            int ch_num = _session.get_ch_num(SR_CHANNEL_LOGIC);
            if (ch_num <= 0)
                sw_depth = LogicMaxSWDepth32;
            else
                sw_depth = LogicMaxSWDepth32 / ch_num;
        #endif
   } else {
You only need to re make the DSView directory and that is very fast, unlike the original full compile, then re install.
Let me know if it works for you. :-)
Regards, Kevin.
Last edited by bleep42 on Tue Mar 09, 2021 9:21 am, edited 2 times in total.

User avatar
bleep42
Posts: 259
Joined: Wed Mar 07, 2012 12:43 pm
Location: Sussex

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Mon Mar 08, 2021 4:19 pm

I've been looking at this code, I really don't understand how the architecture of the host CPU can have anything to do with how much the DSLogic unit can store, so I've now replaced the above code with:-

Code: Select all

    if (dev_inst->dev_inst()->mode == LOGIC) {
                sw_depth = LogicMaxSWDepth64;

//      #if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__)
//          sw_depth = LogicMaxSWDepth64;
//      #elif defined(__i386) || defined(_M_IX86) || defined(__arm__) || defined(_M_ARM)
//          int ch_num = _session.get_ch_num(SR_CHANNEL_LOGIC);
//          if (ch_num <= 0)
//              sw_depth = LogicMaxSWDepth32;
//          else
//              sw_depth = LogicMaxSWDepth32 / ch_num;
//      #endif
    } else {
So now both 32 and 64 bit hosts are the same. I've tested on my DSLogic and it is working just fine on my Pi4 2GB as far as I can tell. :-)
Regards, Kevin.

User avatar
bleep42
Posts: 259
Joined: Wed Mar 07, 2012 12:43 pm
Location: Sussex

Re: [SOLVED] pigpio nanopulse.c example does not work on Pi4B/3B+/2B with Buster/Stretch

Wed Mar 17, 2021 10:20 am

Any one else with one of these DSLogic analyzers, who can confirm that this fix works on ARM?
Regards, Kevin.
bleep42 wrote:
Mon Mar 08, 2021 1:11 pm
Hi Hermann,
Ok I've fixed it, it was an error on the source code, they had a #if define for x86 and x64, but not ARM, as soon as I added it and recompiled, I'm now getting the full use of the RLE compression, if you want it.
modify file where you extracted the tar DSView-1.12/DSView/pv/toolbars/samplingbar.cpp
at lines 555 and 557 change the code to the following.

Code: Select all

    if (dev_inst->dev_inst()->mode == LOGIC) {
        #if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__)
            sw_depth = LogicMaxSWDepth64;
        #elif defined(__i386) || defined(_M_IX86) || defined(__arm__) || defined(_M_ARM)
            int ch_num = _session.get_ch_num(SR_CHANNEL_LOGIC);
            if (ch_num <= 0)
                sw_depth = LogicMaxSWDepth32;
            else
                sw_depth = LogicMaxSWDepth32 / ch_num;
        #endif
   } else {
You only need to re make the DSView directory and that is very fast, unlike the original full compile, then re install.
Let me know if it works for you. :-)
Regards, Kevin.

Return to “C/C++”