No, it’s a bit different than that. I’ll try a different description.
Klipper host talks to the embedded microcontroller, and on the Pico this has to be done over USB1 unless you want to hook up a UART from the Pico over to the Klipper host (You dont want to
). This limits you to 12Mbps USB1 speeds because that’s all the Pico can do. [This is the major failing in the Pico in my opinion- if only that this were USB2… Maybe for Pico 2 that’ll get fixed]
At any rate, the best way to do this would be for Klipper to tell the Pico “Toggle bit 24 on the GPIO expander”. Over on the Pico side of things, it gets that direction and then goes about shuffling all the 24 bits plus other stuff that the shift register needs. All of the bits have to be clocked through the shift registers and then asserted, each time you want to change the state of any one bit.
If you wrote something on the Pico that lets the host Klipper directly access the two pins on the Pico, then instead of telling the Pico “Toggle bit 24 on the GPIO”, Klipper would instead have to go through the entire sequence of clocking the bits into the shift register. The sentence would instead be something like “Send this bit, then that bit, then this other bit…” and so on. This would expand into something perhaps 30 or so times more volume of traffic than just telling the PIco to change one bit.
Edit to add: The command to change that bit also has overhead. Imagine that you can fit the wrapper for that command into say 32 bits. To pump out all of those 30ish bits of shift register commands, each command has to be wrapped in that example 32 bit command. So to make the math easy, you have 12Mbps of the USB1 bus divided by (32 bits times 32 bits) . You’ve turned 12Mbps of interface into 12K commands per second. Those steppers need hundreds of thousands of commands per second when they’re all moving. The system can’t work at reasonable speeds. It would be a turtle of a controller.
All this extra overhead starts to severely limit how fast you can toggle the step/dir/enable bits, and thus starts severely limiting the speeds you can get out of the motors. It also puts a heavier load on the host Klipper and that crappy slow USB1 bus.
So even if the shift register ICs can speak “Whatever”, you still want to use the PIOs on the Pico for the heavy lifting of continuously clocking out the bit pattern of the GPIO state.
That’s I think what most folks miss when trying to think about the GPIO expander. You never send just one bit to the stack. To command a single step bit to one stepper driver, the entire set of bits for every single outpot on all of the GPIO ICs needs to be sent. Every single time any bit changes.