Skip to content

Support for PX Logic devices#284

Open
dogtopus wants to merge 44 commits intosigrokproject:masterfrom
dogtopus:px-logic
Open

Support for PX Logic devices#284
dogtopus wants to merge 44 commits intosigrokproject:masterfrom
dogtopus:px-logic

Conversation

@dogtopus
Copy link

@dogtopus dogtopus commented Feb 25, 2026

Device information

PX Logic (https://marrychip.com/) is a series of low-cost logic analyzers. Four variants exist in the series lineup:

  • Logic 32 (32 channels, up to 1Gsps, 4Gbit hardware buffer)
  • Logic 16 Pro (16 channels, up to 1Gsps, 4Gbit hardware buffer)
  • Logic 16 Plus (16 channels, up to 500Msps, 2Gbit hardware buffer)
  • Logic 16 Base (16 channels, up to 250Msps, 1Gbit hardware buffer)

The device also supports PWM output and dedicated external trigger input/output channels.

The vendor software is open-source and is based on DreamSourceLab DSView. The protocol however does not resemble any of the DSLogic devices other than the sample data format.

I wrote down some notes and named all the used registers when I was reading the code of the vendor software, which can be found here.

About this driver

The driver is mainly targeting the PX Logic 32 variant, although I expect it to work with other device variants due to them using effectively the same protocol with only some parameter range differences. Currently the driver can finish capture cycles, with internal (per-channel) triggering. Both PWM output channels also work over cli. External trigger input/output is not within the scope of this PR due to the fact that it is not very straightforward to implement trigger-only channels in sigrok/PulseView. Additionally, this driver does not attempt to enforce the bandwidth limitation imposed by the vendor software, as to my knowledge most sigrok drivers do not do this by default either.

Configuration options

The driver exposes these extra configuration options:

  • SR_CONF_CONTINUOUS: Configure the device to enter streaming mode when set to true. Without this the maximum number of samples that can be captured will depend on the internal buffer size of the device, since in this case the device will not use the internal DRAM as a ring buffer and will stop capturing once the hardware buffer runs out.
  • SR_CONF_VOLTAGE_THRESHOLD: A range value between 0.0V-0.0V to 6.0V-6.0V in 0.1V increments. This is used by the driver to program the VREF PWM DAC located within the device.
  • SR_CONF_FILTER: Enable the "one sample filtering" hardware feature.
  • SR_CONF_CLOCK_EDGE: Enable the "sample on falling edge" hardware feature when set to falling.

On PWM0 and PWM1 channel groups, SR_CONF_ENABLED, SR_CONF_OUTPUT_FREQUENCY and SR_CONF_DUTY_CYCLE are also exposed, similar to Kingst LA2016 and friends.

Using PWM channel

It is currently not possible to control the PWM channels on PulseView. However it can be accessed through sigrok-cli:

# Enable PWM channel P0 with output frequency of 1kHz and duty cycle of 25%
sigrok-cli -d px-logic -g PWM0 --set --config output_frequency=1000.0 --config output_duty_cycle=25.0 --config enabled=true

The maximum frequency the PWM channels can output is 62.5MHz (half the clock rate of the PWM input clock), however the higher the frequency goes, the lower precision the duty cycle setting gets. Vendor software has a limit on the frequency of up to 1MHz.

Firmware

Firmware files are required for this device. A corresponding PR has been created at sigrokproject/sigrok-util#19 to download such firmware files from the vendor software's GitHub repository.

Data processing

This driver uses a GLib thread pool to implement multithreaded data processing, and uses an async queue to sort the samples before sending them to sigrok. libusb transfers and data ingestion on the sigrok side remain single-threaded.

@dogtopus dogtopus marked this pull request as draft February 26, 2026 07:58
- Do nothing when a stripe has no 1 bit left in it.
- Clear all output bits with memset before flipping some bits to 1, instead of flipping everything manually always.

This makes best case scenario quite a bit faster but worst case scenario will still be slow.
Without this some pending transfers will terminate early.
This is based on a glib thread pool of maximum of 4 threads, and an async queue is used to sort the output efficiently in the unlikely event that the transpose tasks complete out of order. The transpose buffer has been adjusted to attach to every single transfer so the transfer objects can double as sample transpose task descriptors.

This also introduces a helper function to help prevent putting the output state machine into HALT state multiple times.

This unfortunately didn't resolve all performance problems, as some of them seem to stem from sr_session_send being unable to process a large quantity of channels on time. There's nothing we can do about it (except actually maybe not).
This drastically cuts down the CPU usage of sr_session_send when only using lower channels during high speed capturing, by cutting down the amount of otherwise unused bits from disabled channels sent to sr_session_send.

Also pass the correct output buffer to cap_transpose_samples() calls.
- Clear STALL condition on the sample FIFO endpoint before starting capture, as the device will generate a STALL under certain circumstances when capture has stopped.
- Reuse the frequency table when determining the previous set sample rate in px_logic_receive_config.
- Add branch prediction hints in some hot functions.
Sort the code roughly to a more logical order, so it would hopefully be easier to follow.

PWM is not yet supported on pv. To use it, one needs to use the following cli command:

sigrok-cli --driver px-logic -g <PWM0|PWM1> --set --config output_frequency=<freq> --config output_duty_cycle=<duty_cycle> --config enabled=true

Setting individual values besides `enabled` currently does nothing in cli since we only synchronize the values to the device on writing to the `enabled` config key.

Despite the official claim, PWM1 seems to work just fine for me. Although I'd suggest to proceed with caution if you wish to enable and use it.
Turns out the current sigrok architecture makes this awkward to implement. Remove external trigger support from the current scope for now.
@dogtopus dogtopus changed the title [RFC] Initial support for PX Logic Support for PX Logic devices Mar 3, 2026
dogtopus added 4 commits March 4, 2026 01:42
This is basically a replica of the Saleae firmware upload logic (i.e. upload firmware during scan() and wait for reboot in dev_open()).

Also refactored the protocol library to include a "probe" stage that includes functions that only require an open libusb device handle to make requests to the device.
- Use constant pointers for pointer/field aliasing.
- Alias some fields with long names to avoid unnecessary line wraps.
@dogtopus dogtopus marked this pull request as ready for review March 5, 2026 04:39
dogtopus added 12 commits March 7, 2026 01:04
This makes the behavior of PWM configuration consistent with the Rigol function generator driver.
This makes extra headroom for sr_session_send on quad-core CPUs.
This is less efficient when all values were supplied at once but should align with the "common sense" behavior better.
This groups all the register configuration code for capturing at the same place, which will hopefully make the code easier to read.
- Block device running at FullSpeed and lower
- Warn the user if the OS-level transfer buffer limit has been reached.
  - On Linux this defaults to 16MiB and it seems to be 32MiB on Windows (https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-bandwidth-allocation#maximum-transfer-size).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant