spi
Having run out of ideas for simplifying the enclosure (for now), I started digging a bit deeper into the actual protocols through which little cloud’s microprocessor (MPU) could communicate with the individual port microcontrollers (MCUs). The initial idea from a couple weeks back was that the MCUs could act as software-defined USB controllers driven by the MPU, such that they could present themselves as anything from a memory stick to a network card to the worker devices.
However, I’m not sure anymore about SPI as the protocol of choice for having the MPU communicate with the port MCUs. There are a few downsides. First, SPI would require the MPU to explicitly “chip-select” and query every MCU regularly, eroding bandwidth and increasing complexity. Second, we’d need to route 5 or so pins out of each MCU. Third, the USB driver ecosystem doesn’t natively overlap with SPI all too much. I did get to order an evaluation board predicated on this approach before growing skeptical about it, though.
ethernet
Another option for the MPU-MCU interconnect would be Ethernet. In this arrangement, the MPU and MCUs would connect their Ethernet pins to a dedicated on-board switch chip. 100 Mbps seems quite common as a choice of Ethernet speed on MCUs that implement it, which is higher than typical SPI speeds. Plus, it natively supports many-to-many communication, unlike SPI where only the MPU could initiate exchanges as master.
There is also USB/IP, which appears to enable the MCU USB controllers to appear as local, native ports to the MPU. It works by sending USB packets over a network, in our case a network that lives entirely on a PCB. Though USB/IP appears to only handle host roles natively, not so much device roles. We’d also incur the Ethernet switch on the BOM, and Ethernet on MCUs carries a premium. Could we do better?
usb
What if we used the same stack and tooling to connect the MPU with the port MCUs as we do when connecting MCUs to worker devices? The MPU could be the USB host that connects to many MCU devices. Crucially, MCUs would need to have two independent USB buses, a device-only one oriented towards the MPU, and a dual-role one oriented towards the worker devices. An interesting precedent here are those PC-to-PC cables that present themselves as a device to both USB hosts and shuttle data through.
If we could reduce the interconnect protocol to USB, we’d get the benefit of only having to use one stack for both interconnect on the PCB and communication with worker devices. CherryUSB appears to be a very versatile USB library, with strong support for the cheap Chinese MCUs. USB would also only require us to mostly route 2 data pins only out of an MCU, easier than 5. Most MPUs already have dedicated USB silicon, which is not the case for Ethernet. The MCUs might be able to only lightly edit USB packets shuttling through.
We would still need to use a USB hub between the MCUs and the MPU, and two USB buses on an MCU is not too common. But these parts are below 2$ still. I also realized we definitely need high-speed USB at least for having laptops or desktops potentially boot a live OS off of little cloud. Full-speed only would take forever to load the OS in memory. USB hub concurrency is also much more mature than via SPI.
hub
If we have a USB hub IC standing between the MCUs and the MPU, we could also route some of the hub buses out directly to ports. This could enable ports that can only connect to phone or tablet workers, not laptops or desktops, but for a very low cost. If MCUs with two high-speed USB buses grow into a meaningful cost center on the bill of materials, we could potentially offset this by only having some ports with full dual-role data capabilities. I’m not a fan of the broken symmetry across ports, although it could match the real-life e-waste distribution.
switches
Another option I considered briefly that I wanted to mention in the logs was that of analog switches on the ports. Need to emulate a host? Connect the port to a hub IC. Need to emulate a storage device? Connect it to a read-only flash on the board. This would mean lowering the emulation logic down to the hardware level. Though I figured it would be unwieldy to manage and iterate on, besides disabling the option to emulate multiple devices on the same port. I’d rather stick to two-sided high-speed MCUs, potentially occupying only part of a USB hub to the MPU. Driven entirely by the MPU software.





