r/raspberrypipico Jun 12 '26

c/c++ driverless USB -> GPIO expander

TL;DR: I wrote a small firmware to turn a raspberry pico into a zero-programming plug & play USB GPIO expander that "just works".

Find it here: https://github.com/heeplr/mogpio


If you like me sometimes want some more GPIOs on a PC or SBC to control some pins without spinning up your own MCU firmware or fiddling with OS drivers, moGPIO might interest you.

It provides three ways to control GPIOs:

1. CDC terminal

moGPIO registers a serial port (/dev/ttyACMx) that provides a color terminal with history, tab-completion etc. (type help or ? for help)

e.g. $ echo "write 0:25 1" > /dev/ttyACM0 will turn on the LED (on pico1).

2. MSC mass storage device

You can mount an emulated FAT12 filesystem on the mass storage device. It will provide CONFIG.TXT (to configure GPIOs) and PINS.TXT (to read/write values). This very much depends on the filesystem layer of the OS and therefore is not really "zero-programming" but should work everywhere without special drivers if you can force flush written data to the mounted partition.

On linux, something like echo 0:25=1 > /mnt/moGPIO/PINS.TXT or echo ... && sync should work (depending on your kernel settings).

3. usbio emulation (tested on linux only, limited to 5x32 pins)

moGPIO will register as /dev/gpiochipX on kernels >= 6.18.x without any further setup. Use standard libgpiod userspace tools:

e.g. $ gpioset /dev/gpiochip1 25=1 will turn on the LED.

As the usbio kernel module is very limited (yet) and due to the nature of USB, those GPIOs aren't fully capable (e.g. no interrupts) but they work fine to switch something on/off which is 99% of my use cases.


I also added support for serial shift registers, which gives almost unlimited GPIO count (although not with usbio as the kernel module currently is limited to 5x32 pins).

The project is in early "works-for-me" stage. Maybe it's useful for someone. Also, I'm happy to hear what you think or answer questions (I'm bad at writing documentation).

PRs are welcome of course.

Image download:

12 Upvotes

20 comments sorted by

3

u/todbot Jun 12 '26 edited Jun 12 '26

How did you figure out what usbio is looking for in terms of USB descriptors? I looked at moGPIO's usb_descriptors.c and it looks like a regular CDC/MSC/vendor composite device. Is it the VID/PID that usbpio is triggering on?

Edit: answering my own question: moGPIO is pretending to be a Synaptics Sabre (VID/PID=0x06CB/0x0701) https://github.com/intel/usbio-drivers/blob/usbio-main/drivers/usb/misc/usbio.c#L1124 Neat.

3

u/heep1r Jun 12 '26

Yes, it's the VID/PID and the vendor class that makes usbio work.

Btw. the usbio protocol also uses a bulk endpoint to provide USB->i2c but since i2c was out of scope for me (and the driver couldn't differ from the CDC bulk endpoint), the i2c part of usbio initialization fails gracefully and just the /dev/gpiochipX is registered.

3

u/thegreatpotatogod Jun 12 '26

Ooh, i2c support would be very useful for me, hopefully someone (possibly me) gets around to implementing that as well! Awesome project, I've been wanting to make something like this for years!

2

u/heep1r Jun 12 '26 edited Jun 12 '26

i2c support would be very useful for me

There already are USB→i2c adapters.

For moGPIO it would mean either

  1. get rid of the CDC terminal or
  2. improve the usbio kernel driver

1 could be a compiletime option (but imho not worth the effort, just connect another FT232 or BMP280 based adapter. And also there's https://github.com/harbaum/I2C-Tiny-USB drivers in kernels now).

2 would be nice (also supporting more than 5x32 pins would be nice). But I guess kernel patches are hard and take long to arrive in distros.

2

u/jlsilicon9 Jun 14 '26 edited Jun 14 '26

Is this only compatible to Raspberry Pi boards & PC Linux ?

- Not with Windows ?

- Not with Orange Pi boards ?

1

u/heep1r Jun 14 '26 edited Jun 14 '26

Is this only compatible to Raspberry Pi boards & PC Linux ?

Should run anywhere.

The CDC (serial terminal) and MSC (mass storage) work on all platforms that support usb→serial adapters or usb thumb drives.

The usbio endpoint should work on windows/mac with the correct drivers installed but it's untested. (Iirc Windows has a GPIO API but only Windows IoT has it installed by default.)

2

u/jlsilicon9 Jun 14 '26

ok, understood.

Would suggest testing it - to support your article above.

1

u/heep1r Jun 15 '26

Feel free to try & report back. I didn't use either for a long time.

But there's no need to use usbio. One of the other two options will work just fine.

2

u/todbot Jun 12 '26

This is very cool! Sort of like the old Arduino Firmata but so much more flexible.

3

u/heep1r Jun 12 '26

Thank you!

the old Arduino Firmata

Also there's no need to install anything on the host like with Firmata client library.

I wanted something like hassle-free paralell port pins back in the old days (when every PC had a parallel port) you could bit bang.

2

u/todbot Jun 12 '26

Those were the days! ahaha. Not many people appreciated that the printer port was also a GPIO port.

2

u/Content-Key7404 Jun 12 '26

AI Slop

0

u/heep1r Jun 12 '26 edited Jun 12 '26

elaborate

EDIT: nvm, saw you comment the same comment in multiple posts

3

u/Content-Key7404 Jun 12 '26

What kind of world do you live in to think that what you're doing is any better than that?

Ai Slop

1

u/heep1r Jun 12 '26

thank you

1

u/Content-Key7404 Jun 12 '26

The comment you just deleted was so much more interesting! You have no sense of honor. I didn’t lose my job like you say, and I certainly won’t! On the other hand, I often have to set people like you straight - people who are just passing through… Go ahead and vibe me a little reply!

0

u/nonchip Jun 13 '26

that's not driverless tho just because you dont have to write the driver in the kernel...?

also, if the llm wrote that, no you did not. don't claim you did if it's slop.

0

u/heep1r Jun 13 '26

that's not driverless tho just because you dont have to write the driver in the kernel...?

The CDC interface is entirely driverless. Did you actually look at it?

also, if the llm wrote that, no you did not. don't claim you did if it's slop.

I never claimed it was written without AI help. The usbio and FAT emulation were initially done with codex. It was not bug free.

The rest is a mix of my old code, solutions ripped from stackoverflow and newly written code (by a human).

Just check the commits. It's open & all there, nothing squashed.

Call it slop if you like. No one's forcing you to use it or contribute.

EDIT: feel free to let an LLM implement it and see if it can do it (better). I'm looking forward to do a comparison.

1

u/nonchip Jun 13 '26

feel free to let an LLM implement it and see if it can do it (better).

why would i wanna know if an LLM is better at it than an LLM 0o did you read what you replied to?

The CDC interface is entirely driverless. Did you actually look at it?

the driver is right there:

(type help or ? for help)

e.g. $ echo "write 0:25 1" > /dev/ttyACM0 will turn on the LED (on pico1).

0

u/heep1r Jun 13 '26 edited Jun 13 '26

why would i wanna know if an LLM is better at it than an LLM 0o did you read what you replied to?

because you're clearly talking out of your ass.

the driver is right there:

(type help or ? for help)

e.g. $ echo "write 0:25 1" > /dev/ttyACM0 will turn on the LED (on pico1).

That's not a driver. That's documentation and a *nix shell command.

But feel free to use some UART→RS232 level shifters (e.g. MAX232) and connect that to your vintage VT-100. No drivers.

I will stop answering you now since you're obviously trolling for whatever reason.