- Published on
ADALM2000 + Sigrok
- Authors
- Name
- Sean Jasin
- @sean.w.jasin
Background
The ADALM2000 (M2K from here on out) is an educational board for analyzing circuits. It has amazing hardware specs for students and hobbyists going into electrical/computer engineering.
Hardware
- 2 Channel Analog I/O
- Oscilloscope
- Arbitrary Wave Generator
- 1 Channel Voltmeter (according to website)
- Uses same channels as oscilloscope
- 2 External Triggers
- 2 Programmable Power Supplies
- Positive rail +5V MAX
- Negative rail -5V MAX
- 16 Channel Digital I/O
- Logic Analyzer
- Pattern Generator
- 16 Channel Virtual I/O
Pre-existing Software
The M2K uses Scopy software. While this software is certainly usable, it runs into certain issues such as freezing or outright crashing. In addition, changing the parameters in the decoders will sometimes cause the decoder to stop displaying correctly.
However, in credit to Scopy and its maintainers, the project is open source and the maintainers respond to new issues pretty quickly. As of the day this is posted, the maintainers have fixed the issue within the next release of Scopy (not currently out as of posting either).
Why
I wanted to decode UART signals using the Scopy software. However, I ran into issues decoding the signal when using Scopy software. Not to mention I also kept running into crashes when having the power supply and logic analyzer on at the same time. In fairness to Scopy, I won't be using the power supply options when using the M2K with Sigrok.
Actually porting
Goal
Finish a roughly working M2K driver for libsigrok before the next release of Scopy.
Things to learn
- libsigrok - the backend for the Sigrok project
- libiio - Used to interact with the M2K
- Compiling projects with extra dependencies (libiio)
- cmake
- m4
- make
- pkg-config
Challenges
- libsigrok has very sparce documentation for creating a new driver
- libiio has outdated information for v1.0
- better than no documentation at all from 4 years ago
- example code in repository is sparcely commented
How does thing A or thing B work?
Due to the lack of documentation of how libsigrok drivers work, I had to look through older/already existing drivers from the past to get an understanding of how it worked. A massive reference for me was an old pull request for the M2K which was closed because certain ADI developers stated they were going to implement a libsigrok driver themselves. However, there was no new pull request for an M2K driver. So here I am implementing it again.
As for libiio. A lot of learning libiio was guess and check. I have an entire repository dedicated to figuring out how libiio works called iio examples. The issues I ran into are documented in the Issues
section of github. I plan on updating the documentation more thoroughly if others begin to use the iio examples
repository. However, for now, I will only be documenting issues I run into.
After figuring out how each libiio and libsigrok worked (very roughly). I was able to make a very rough driver for libsigrok that functioned in Pulseview, the GUI frontend for libsigrok. You can see my progress in the commits
section of github on this forked repo
Compiling
Honestly, the process of compiling ended up being just as annoying as figuring out libiio and libsigrok worked. When compiling libsigrok for the first time I run into missing library because libiio isn't normally included in libsigrok. Ok, use CFLAGS="-liio"
before the ./configure
command.
Great! However, system libiio is v0.25 instead of v1.0 because libiio for my OS hasn't been updated to v1.0. Ok then, install the git v1.0 libiio to /usr/local
directory so it doesn't interfere with my OS's libraries.
Awesome, now I have the libiio version I want to use, but I run into another problem. pkg-config
doesn't see libiio v1.0 when compiling and yells at me. Fine, just point it towards the right pkg-config using PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
before running ./configure
. Finally everything compiles! :D
By this point everything seemed ok. However, pulseview wouldn't use my libsigrok driver. Turns out, I need to point it to the library using LD_LIBRARY_PATH="/usr/lib"
before running ./pulseview
While this doesn't look like it would be that annoying, I had no clue how these build systems worked prior to this project (cept for Makefile). A lot of forums (from the past) stated that the library wasn't installed, but that was clearly not the case. It's just that the library was somewhere else. So I just hopped around the internet until I found out. Which was more spread out than just looking at libsigrok and libiio code.
Closing
Overall creating a rough driver took about 10 days and felt pretty exhilarating! As of today, I'm still waiting to see if my driver will get merged into the main repository for libsigrok. If it does get merged, I plan on maintaining it and adding more features. However, if not, I still learned a lot of new things by starting this project.
I had absolutely no clue what this process was like going into this project but, I learned a lot about build systems and reading code along the way which is cool! Still not quite sure if my way of including libraries is the "correct" way of including libraries, but it works for what I needed it to do.