Scope on Bus Pirate LCD by Paul Campbell

Paul, who I’ve had the pleasure to see many times in Shenzhen, made a scope mode for the Bus Pirate. It captures at 500KSPS, has triggers and zooms in and out on the LCD. It’s very cool!

Check out the demo:

  • program scope.uf2 into your FB
  • go into mode 7 using the ‘m’ command
  • set the I/O power supply to 3.3v using the ‘w’ command (w n )
  • set the trigger to ‘both’ enter t to get into trigger mode and then press ‘b’ press to exit
  • start the display with (sr 2n ) that starts the display on pin 2 in normal mode
  • next turn on the pullups (P ) you should see trace with a rising edge
  • and turn them off with a (p ) you should see an exponential decay curve
  • turn them on again with P then enter trigger mode with t and then enter + to only trigger on rising edges then to leave trigger mode
  • start a clock on pin 2 with (G 2 1ms 33% )
  • enter x mode (x ) you should see a bunch of square waves, try + and - to change the scale, and the left and right arrows to move around. Freeze a trace by typing ‘o’.
  • enter y mode and change the voltage scale with + and - (and use the up down arrows to move the display)

AMA - you’ll find the current code in the ‘scope’ branch in the above github repo

Welcome to the forum! I had so much fun trying the scope.

I added you to the git repo as well, push as you like :slight_smile:

// private variables
static uint8_t mem_buffer[SPI_NAND_PAGE_SIZE + SPI_NAND_OOB_SIZE];
static bool allocated = false;

// public function definitions
uint8_t *mem_alloc(size_t size)
    if (!allocated && size <= sizeof(mem_buffer)) {
        allocated = true;
        return mem_buffer;
    else {
        return NULL;

void mem_free(uint8_t *ptr)
    if (ptr == mem_buffer) {
        allocated = false;

Here is the bit of code used in the NAND flash to allocate a shared buffer resource. It’s nothing fancy.

Both logic analyzers I ported seem happy to do their ping pong DMA in a single 32K aligned variable of 128 * 1024 bytes.

1 Like

Hey Paul - Scope mode is merged into main. It’s really awesome, you did a nice integration with the existing commands. Thank you so much for contributing this amazing feature.

I added your .md documentation to the docs site with some photos for the quick start. The LCD was a bit tricky to photograph, we may take another stab at it. I also added the d-isplay mode command to the command reference.

I’d like to mull over the hd help, and sr ss t x y. You were right about the display mode being a major new concept. I feel like there should be a nice command line like way to wrap everything up consistently, but I’m just not seeing it yet. I’d like to lean into the display mode and make the commands consistent across modes. For example, someone asked about logic analyzer on the display: x y t all apply there too, and for that matter sr and ss. Maybe they can be reused in “default” mode to add user pin labels, something like that.

I also added a crude ownership variable in system_config for the big buffer, and show the current owner in the i-nfo screen. I’m not sure it will stay there, but I want it for debugging the logic analyzer (USB, not on the display yet) this coming week. One thing I noticed is that if you’re in scope mode, and use d to enter scope mode again, it errors about the buffer ownership. This also makes me feel like display modes could be handled like the protocols: an array of function references for each display mode with setup_exec, setup, and cleanup, sr,ss,x,y,t. I have some thoughts, but I probably need to build out another display mode (maybe default) and then see how the common bits all fit together.

I’m super excited to see you’re using the CH32V003. I bought a dev board, and someone in Belgium is also sending one. I hope to push into that later next week. The timing of the SW interface doesn’t look exactly like 1wire to me, but I can change the timing in the 1-wire PIO to get the best data rate with the shortest bit times possible. It looks like a cute interface to poke at registers, even manually. This is another place where I feel like BP5 is holding onto too much legacy v3 thinking. Your tweet was right, you absolutely need to be able to do a protocol mode and program/debug without switching modes. This is another place where it feels like there should be a consistent command line utility-like way to manage programmers/debuggers/loaders independently from the protocol mode. I’m not even sure it’s right to have a paradigm of a protocol mode, why not just load/enable functions on pins? Doing it with a clean intuitive interface will take some work though.

1 Like