notro / pico-usb-io-board

Raspberry Pi Pico USB I/O Board
Creative Commons Zero v1.0 Universal
63 stars 14 forks source link

Feature Request: Enable ADC 3 for measuring VSYS #7

Open g-v-egidy opened 5 days ago

g-v-egidy commented 5 days ago

I've been using your pico-usb-io-board firmware for a few days, mostly to make I2C components accessible from within linux. This works really convenient, thank you for making & publishing this.

I found one thing that I think that could be improved: Make ADC 3 available as IIO ADC the same way as ADC 0, 1 and 2.

Why?

When using the firmware on an original RasPi Pico ADC 3 is wired to a voltage divider set up to measure VSYS, the input voltage usually supplied via USB. The RP2040 on the Pico PCB doesn't directly run from this, but uses 3V3 that is created with a quite powerful Buck/Boost regulator that allows it to run from a wide range of voltages. So the RP2040 will probably work flawlessly even in cases of extreme voltage drop on the USB cable. Now consider you have connected some other components to USB Vbus / VSYS that use a linear regulator instead and thus require for example at least 4.3 V to work. Being able to measure VSYS on ADC 3 would allow to automatically verify that these conditions are met.

When using the firmware on some other RP2040-based PCB ADC 3 could be free to use for some other application there and not be tied to measuring VSYS.

For me it is currently the first case, but it could be very well that I create a custom PCB with a RP2040 to use with the pico-usb-io-board firmware in the future.

notro commented 22 hours ago

This is a very low priority project for me so I don't know if there will be any more releases, but if it happens I've put your request in my TODO.

After a quick look at the code I think these changes might be what you need in case you should go ahead and build the firmware yourself:

dln2-adc.c:

-#define DLN2_ADC_NUM_CHANNELS   3
+#define DLN2_ADC_NUM_CHANNELS   4

-        for (uint pin = 26; pin <= 28; pin++)
+        for (uint pin = 26; pin < (26 + DLN2_ADC_NUM_CHANNELS); pin++)

main.c:

-    uint32_t unavail_pins = (1 << 29) | /* IP Used in ADC mode (ADC3) to measure VSYS/3 */
-                            (1 << 24) | /* IP VBUS sense - high if VBUS is present, else low */
+    uint32_t unavail_pins = (1 << 24) | /* IP VBUS sense - high if VBUS is present, else low */

Glad you've found use for this little project, it was fun putting it together.