This project is based on designing and developing a USB 2.0 to embedded serial communication bridge. The formfactor is a small PCB module (system on module - SOM) with a logic device, user indication discrete IO, LEDs, a USB connector and headers.
I'm looking in to other packaging options depending on what people find valuable, but current prototypes utilize through hole rectangular 0.05" pitch headers.
When the bridge receives a USB packet (64 bytes) from one of the USB interfaces it automatically takes that 64 byte packet and sends it out of the serial port (SSI TX port) packaged in a 68 byte frame to the connected embedded system.
The embedded serial interfaces work with 68 byte frame sizes. The first two bytes are headers denoting which USB interface (HID0, HID1 or BULK2) the frame is associated with. The next 64 bytes are the USB packet (payload) and the last two bytes of the frame are currently unused.
The purpose of the bridge is to receive 64 byte USB packets from software and translate them to 68 byte SSI/SPI frames which are automatically sent to an embedded system attached. It also receives 68 byte frames from an attached embedded system and translates those to USB packets automatically sending them to software via the correct USB interface.
2. Software InterfaceThe bridge allows software engineers to send data to embedded systems in a more flexible and organized fashion. From the software perspective there are three interfaces exposed allowing software engineers to logically separate traffic between data paths as well as access internal configuration registers of the bridge.
As can be seen above, the USB link supports 3x different interfaces. Two of these interfaces are HID (interrupt) interfaces. The HID0 interface supports internal bridge register access and configuration. The HID1 interface is a data path. This is a low data rate path (64kB/S per USB spec) and is added because it supports a deterministic poling latency of 1mS.
The third USB interface is a BULK (BULK2) interface supporting higher throughput and as of now is on the order of 750kB/s (kBytes/Second) or 6MBit. This setup affords the software engineer control over the bridge configuration as well as two separate data paths (which do not impact each other's bandwidth) to logically partition data transfers.
Another key improvement in this design (compared to other bridge solutions) is the software driver freedom available to the software engineer. The bridge automatically negotiates the loading of the WINUSB windows kernel driver for the user. From here, the software engineer is free to choose a 3d party user space driver or write their own user space driver. For users, who are looking for a quick plug-and-play feel, a 3d party user space driver such as libusb1.0 can be used in either C++ or Python. For more custom or advanced applications a user space driver can be written from scratch.
The embedded interface consists of two unidirectional synchronous serial ports (SSI/SPI ports). One interface is for transmit from the bridge to the embedded system and the other is a receive from the embedded system to bridge.
The configuration register space allows for many different types of user settings such as:
- SSI Port Clock Rates
- Operational status (buffers full, empty etc...)
- SSI Frame Timeout Capability
- Non-volatile Memory Config Parameter Storage
- Frame Counter, Error Flags etc...
- Data path En/Dis and many more
The embedded interface was split into two unidirectional interfaces to separate transmit traffic and frame parsing from receive traffic and frame parsing. The purpose of this is to relieve congestion one would experience using a single SSI/SPI port as well as allow the embedded system side to send and receive in parallel.
With this design there is also no need to poll the bridge checking for available data to be read. The bridge automatically sends any USB traffic received over its embedded SSI TX interface to the attached embedded system. This means, from the attached embedded system's perspective, data is sent asynchronously similar to an interrupt.
As mentioned earlier, the bridge takes each 64 byte USB packet (all USB interfaces use the same 64 byte packet size as defined by the USB 2.0 spec) and from that generate a 68 byte frame. This is done by adding two bytes in front of the USB data packet and two bytes after the USB data packet. This effective "wrapping" of the USB data packet allows the bridge to add useful metadata for the embedded system's engineers.
Right now the only metadata added is a header value indicating which USB interface the 64 byte data packet was received on.
As shown above, each data transmission to or from the embedded system side of the bridge must be in a 68 byte frame format. The bridge can be configured with frame timeout options as well as an "auto recovery from timeout" option to prevent any hanging if a partial frame is received. If these options aren't used the bridge waits to receive a 68 byte frame before the payload is packaged and sent to software via the USB interface.
The embedded systems engineer can control which USB interface the frame payload is sent through by setting the frame header to the appropriate USB interface ID number. This works the other way around as well. Upon receiving a frame from the bridge, the embedded systems engineer can check the frame header to see which USB interface the 64 byte USB payload came from.
4. ConclusionThe goal of this project is to design and build an embedded communication bridge that allow people to seamlessly send USB 2.0 full speed data to an embedded system with more flexibility and function. It also supports embedded system communication to software in the reverse direction just as seamlessly.
This platform fills the gap between slower serial ports with 1Mbit or less baud rates and high speed links which are hard to implement like USB 2.0 HS, USB 3.0 or gigE. Although there is a much improved performance and flexibility aspect, these modules are as easy to use as a standard serial port.
Some of the benefits of this approach over current solutions:
- No proprietary drivers (kernel or user space)
- Kernel driver auto negotiated and loaded (WINUSB for now)
- Logically separate data paths for communication (HID1/BULK2)
- Bridge config registers modified by USB or SSI/SPI interfaces
- Small form-factor
- Discrete IO for flow control
- Register accessible buffer status for flow control
- Separate RX and TX embedded synchronous interfaces
- Average data throughput of 750kB/S (6Mbit/S) (BULK only)
- Large internal frame buffers in logic device for RX and TX interfaces
The current status of this project is the prototype phase. I have first article hardware prototypes in the lab. The average throughput of 750kB/S was measured on these prototypes.
The majority of the firmware is developed and running including most of the internal bridge functional features which have not been covered here other than the mention of the frame timeout and recover mechanism.
6. Next StepsMy next steps are to gather feedback and share this concept with others. I hope to improve and add features that the community finds useful as well as gauge the overall value to others for a module like this.
I would also like to explore other options allowing the size of the module to shrink. Some examples I would be interested in getting feedback on are below:
- Components on top and bottom of PCB to shrink size for through hole model (which this project shows)
- Castellated vias model to eliminate rectangular headers on the side
- Possible interest in a USB 2.0 high speed version
Thanks for your time reading about this project. Hopefully more posts will come showing operational features and performance as they develop.
Please provide feedback regarding features, thoughts and perceived value of a module like this!


Comments