Great Scott Gadgets

open source tools for innovative people


2023 Winter Break

We hope everyone has a great holiday season! If you are trying to get in touch with the Great Scott Gadgets team please know tomorrow (December 22nd) will be our last day in the office until the 2024 calendar year! This means that we will not be available through email, on Discord, or via GitHub. See you all in January!


Free Stuff - September 2023

The September recipient for the Great Scott Gadgets Free Stuff Program is Erik. Erik is an Ojibwe filmmaker and artist. He has only had his amateur radio license for a short while but he is already assisting in running community demonstrations on how amateur radio can help in emergency situations. We are sending Erik a HackRF One so he can build a mobile training station and take his emergency preparedness demonstrations on the road to Native communities. As an avid camper and road tripper, Erik is also excited to eventually take his demonstrations into wilderness settings and rural communities. We look forward to seeing Erik’s mobile training station and getting updates on where he has taken it.


Improvements to Cynthion Hardware

Note: This is a crosspost of a Cynthion update on Crowd Supply: https://www.crowdsupply.com/great-scott-gadgets/cynthion/updates/improvements-to-cynthion-hardware

Since our last hardware design update in April, we have been hard at work refining the Cynthion design in preparation for production. Believe it or not, we’ve completed and tested six design revisions since r0.6 described in April!

In r0.7 we increased the maximum pass-through current by selecting FETs with lower resistance and by improving heat dissipation of the PCB layout. We added filters to the buttons, reducing the need for debouncing in firmware and gateware. We added a zero ohm series resistor to the oscillator so that it could be replaced easily with a higher resistance if indicated by electromagnetic compatibility (EMC) testing. We also updated several component selections and added or removed various pull-up and pull-down resistors, ensuring that we follow recommendations for the FPGA and microcontroller.

After testing these improvements, we decided that the design was ready for pre-production. We updated a few component selections, refined some nuances of the PCB layout, and bumped the hardware version number from r0.7 to r1.0.0.

Hardware Semantic Versioning

At this time we adopted an internal standard for hardware semantic versioning. It can be difficult to know how to version hardware designs, so we chose to make our decision process easier by establishing a set of rules adapted from the popular semantic versioning standard for software. While the software semantic versioning standard is focused on the software’s Application Programming Interface (API), our standard for hardware focuses on the hardware/software interface.

As an example, a change to the PCB layout that has no affect on software would warrant a bump from 1.0.0 to 1.0.1, but swapping pin assignments on a microcontroller (necessitating different firmware behavior) would require the version number to be bumped from 1.0.0 to 1.1.0. While software version numbers are often prefixed with “v”, we use “r” for hardware, making it easier to tell if we are referring to a software version or hardware version.

Although r1.0.0 differed very little from r0.7, we bumped the major version number to indicate that it was the first version handed off for volume production. It later turned out that further revisions were required, but r1.0.0 was the first version that conceivably could have ended up in your hands.

The Component Shortage Strikes Again

As mentioned in Cynthion Delivery Timeline Update, we soon learned that the power monitoring component used in r0.6 through r1.0.0 was no longer available. While many thousands were available just three weeks earlier, they all had vanished in the short time between prototyping r0.7 and purchasing components for production!

Fortunately, we were able to find just enough of an alternative component, so we snatched it up and designed and tested another revision, r1.1.0, using the new part. Because the new part is the same IC in a different package, nothing needed to change in r1.1.0 except for the PCB layout and some pin assignments.

Around this time, we received new enclosure samples, updated for the larger PCB size introduced in r0.6. The samples were great, but we noticed that they made the buttons feel inconsistent. It was very difficult to center the PCB in the enclosure such that the button plungers all extended the same distance. A certain amount of play in the placement of the PCB within the enclosure is unavoidable, but for some reason it seemed to be nearly impossible to center the PCB perfectly.

Upon further investigation, the problem turned out to be with the PCB design, not the enclosure. When I had added a new button in r0.6, I accidentally placed it 0.1 mm closer to the PCB edge than the other two buttons. It wasn’t noticeable at first, but, once the board was placed in an enclosure, it was possible to feel the difference! We corrected this tiny discrepancy in r1.1.1.

Electromagnetic Compatibility Challenges

After our first round of EMC pre-compliance testing we hoped that we would be able to pass a second round with some software modifications and minor hardware updates (such as increasing the value of the oscillator series resistor). While some of these measures were effective, they weren’t enough to pass the emissions test. After our second test we determined that another hardware design revision was required to reduce electromagnetic emissions.

In r1.2.0 we significantly improved power supply connectivity and decoupling for the FPGA which seemed to be the principal remaining source of emissions. Most of these changes were enabled by updating the PCB from four layers to six. Additionally we added series resistors to the ULPI bus that connects each USB PHY to the FPGA. We suspected that these resistors may be unnecessary (except perhaps the ones on the ULPI clock signals), but it is much easier to swap in different resistances than it was before we added those resistor array footprints.

Our next pre-compliance test clearly indicated that we had successfully quashed emissions from the FPGA, but the we still had a borderline result. One of our configurations passed the test but with very little margin. We felt that we needed to reduce emissions further to ensure success in the formal test.

With the FPGA noise out of the way, it had become possible to detect emissions from the USB PHYs. After some experimentation, we determined that these emissions could be reduced with further modifications to the PCB design and enclosure.

We addressed PHY noise in r1.3.0 by improving shielding and PHY power supply decoupling and by installing common-mode chokes on the USB data signals. Additionally we made a change to FPGA control that makes it easier to recover a Cynthion bricked by bad gateware, and we fixed a power supply start-up bug that was introduced in r1.2.0.

I’m pleased to report that r1.3.0 passed EMC pre-compliance testing! There are some small bugs that need to be corrected in one more hardware revision, but we are now confident that Cynthion will pass the formal EMC test.

Viewing the Design

Most of the changes since r0.6 are unlikely to ever be noticed by a Cynthion user, but they all enhance the quality of the product in some way. The most significant functional change is that pass-through power now supports up to 3 A of current.

Design documents and fabrication outputs for each of these hardware revisions have been released in the new cynthion-hardware repository. Previously the design was included in the LUNA repository which now contains only the LUNA gateware library.


Free Stuff - August 2023

The August recipient for the Great Scott Gadgets Free Stuff Program is The Factory, a student-run hardware design lab at McGill University in Montreal, Canada. The Factory aims to give students access to advanced tools for their hardware projects, space to work on their projects, and support in developing technical skills.

The Factory has previously offered workshops on VIM, VHDL, C, and PC building. They also run a Hackathon called The Forge. In one instance of The Forge students formed teams and built a line tracing robot to race against the other teams. In non-event related times, students in this lab have completed projects such as an IoT system for the trash cans on the McGill campus to alert the cleaning teams when a trash can is full, custom video game controllers, and an automated watering system for plants. About 40-50 students currently frequent The Factory, and they are all passionate about electronics, hardware, and related research.

We are sending The Factory a HackRF One so their lab members can fulfill their hopes of offering workshops and creating materials on wireless systems, satellite communication, and spectrum analysis. Good luck and have fun!


Moondancer: A Facedancer backend for Cynthion

Note: This is a crosspost of a Cynthion update on Crowd Supply: https://www.crowdsupply.com/great-scott-gadgets/cynthion/updates/moondancer-a-facedancer-backend-for-cynthion

One of the core features promised in the Cynthion announcement is the ability to create your own Low-, Full- or High- speed USB devices using the Facedancer library – even if you don’t have experience with digital-hardware design, HDL or FPGA architecture. If you’ve been eagerly anticipating this feature, we’re pleased to introduce Moondancer, a new Facedancer backend for Cynthion.

What is Facedancer?

Facedancer is a host-side Python library for writing programs that remotely control the physical USB port(s) on Facedancer boards such as the original Facedancer21, GreatFET One, and Cynthion.

Using Facedancer to control a physical USB port gives you direct control over the data encoded in USB streams and allows you to do things like:

  • Emulate a physical USB device such as a keyboard, mass storage device, or serial interface,
  • Act as a programmable proxy between a device and its host with the ability to inspect and modify the data stream,
  • Fuzz host-side USB device drivers by deliberately sending malformed data that can trigger faults in the device or host software.

Facedancer Example

Let’s say you need to automate the operation of a computer running some software that can only accept input via keyboard:

A USB keyboard connected to the Target Operating System.

By connecting a Facedancer board such as Cynthion to the computer (called the “target”) in place of the USB keyboard, you can now use a second computer (called the “host”) to run a small Python script to control USB traffic between the target computer and Cynthion:

A Facedancer emulation of a USB keyboard connected to the Target Operating System.

Whenever a new USB peripheral is plugged in, the target operating system will first send a standard set of USB enumeration requests to the peripheral asking it to identify itself to the operating system. In the diagram above, Cynthion is the peripheral receiving enumeration requests from the target. However, instead of replying directly, Cynthion will forward any enumeration requests it receives to the Facedancer host. The Facedancer host will then respond to the target with a set of USB descriptors corresponding to the peripheral you are emulating. Once the target operating system has received a set of known USB descriptors, it will load the appropriate device driver for controlling the USB peripheral. All subsequent USB transfers initiated by the device driver will also be received by Cynthion and forwarded to the Facedancer host. By using a Facedancer emulation that responds appropriately to the command set of the peripheral being emulated, Cynthion can respond to the target operating system as if it were any actual physical device.

In our example, we can use Facedancer’s USBKeyboardDevice object to provide the USB descriptors and transfer commands required for a keyboard that follows the USB human interface device class specification:

import asyncio
from facedancer.devices.keyboard import USBKeyboardDevice

device = USBKeyboardDevice()

async def type_on_keyboard():
    # Type ls.
    await device.type_letters('l', 's', '\n')

main(device, type_on_keyboard())

What is Moondancer?

Moondancer is a new backend for Facedancer that adds support for Cynthion.

Facedancer supports a variety of boards by providing different backends for each supported board. For example, GreatFET One uses a backend called “greatdancer” while RPi + Max3241 boards use the “raspdancer” backend. In keeping with Cynthion’s lunar origins, we decided to call the new backend “Moondancer”.

What makes Cynthion different from other Facedancer-compatible boards is that, instead of being based on a microcontroller, it is built around an FPGA connected to three USB 2.0 PHY chips under control of the open source LUNA USB gateware library. While this provides us with more direct access to USB signals and their behaviour it also represented a significant engineering challenge for our team. The most significant challenge was how to control the USB controllers. On previous Facedancer devices, the controllers have been under software control via device firmware running on the device CPU. However, being an FPGA-based platform, Cynthion does not have a CPU!

At first glance, we had two choices for controlling the USB 2.0 PHY chips:

  1. Implement the control logic as gateware.
  2. Integrate a microcontroller into the Cynthion hardware design.

In principle a Facedancer device merely acts as a forwarder between the USB controllers and the controlling host. This means a gateware implementation could be as simple as exposing the registers controlling LUNA’s “eptri” triple-fifo endpoint peripheral via a set of USB Vendor Class commands. On the other hand, integrating another microcontroller into Cynthion would increase the design complexity significantly and add substantially to the bill of materials cost. All things being equal, we may have ended up with a gateware implementation were it not for the recent emergence of high quality, libre-licensed RISC-V implementations. Hosting a microcontroller as a “soft-core” on an FPGA is not a new idea but RISC-V’s open Instruction Set Architecture (ISA) removes many barriers to implementation such as licensing, compilers and tools. Therefore, while a Facedancer device implementation in gateware would be a very cool hack indeed, we thought it would be even cooler to take an approach that would also let you use Cynthion as a tool for getting started with RISC-V, System-on-Chip (SoC) design, and Embedded Rust while exploring USB in embedded environments.

How does Moondancer work?

Moondancer consists of several distinct components:

  1. moondancer-soc: A custom RISC-V SoC that integrates a libre-licensed RISC-V CPU with the LUNA USB peripherals.
  2. lunasoc-pac and lunasoc-hal: Embedded Rust support crates for moondancer-soc peripherals.
  3. smolusb: A lightweight, low-level USB stack appropriate for LUNA USB device controllers.
  4. Moondancer firmware: The device-side implementation of the Facedancer command protocol.
  5. Moondancer backend: The host-side Facedancer backend for communication with the Moondancer firmware.

moondancer-soc

At the heart of Moondancer lies a stripped-down RISC-V SoC design described in the Amaranth Hardware Description Language (HDL):

  • SpinalHDL VexRiscV CPU
  • Full RV32IMAC instruction set support
  • 60 MHz clock speed
  • 64 kilobytes of SRAM
  • 4 kilobytes L1 instruction cache
  • 4 kilobytes L1 data cache
  • 2x GPIO peripherals
  • 6x LED peripherals
  • 1x UART peripheral
  • 1x Timer peripheral
  • 3x LUNA USB eptri peripherals

While the feature set may be modest in comparison to most commercial micro-controllers, the full gateware source of every single component integrated within the design is libre-licensed with all four freedoms intact.

Moondancer SoC Architecture

After bringing up our “hardware” platform for the Moondancer firmware, we faced another set of challenges. In commercial SoC development, there are usually multiple teams tasked with creating the tooling, device drivers and development libraries for a new design. While we would still have to develop device drivers and libraries, we did not need to create yet another fork of GCC to implement our own custom toolchain with compiler, debugger, linker, and sundry utilities. Thanks to the efforts of many contributors, both commercial and from the broader community, the GNU toolchain has been shipping RiscV support for some time now, and Rust (via LLVM) can compile binaries for many RiscV variants right out of the box.

None of this would have been possible even a few years ago, and it is thanks to the efforts of a wide community that we were able to do it within the time and resources available to us:

lunasoc-pac

One of the fundamental building blocks in any Embedded Rust project is a Peripheral Access Crate (PAC) which provides safe register-level access to the processor’s peripherals. While there are already existing PACs and even HALs for RISC-V chips from companies such as Espressif and AllWinner there existed no equivalent for working with a custom-defined SoC implemented as gateware.

Fortunately, what most Rust PACs have in common is that their code is largely generated from an SVD description of the processor and its peripheral registers with the help of the svd2rust tool. Therefore, we extended the luna-soc library with the ability to export SVD files generated directly from the SoC design allowing anyone to easily generate a PAC for any luna-soc design.

lunasoc-hal

While it is entirely possible to develop an entire firmware using just a PAC crate, it would be nice to offer a friendlier programming interface and the possibility of code re-use across different processors. Normally, a chip will come with some form of vendor-provided HAL that provides higher-level abstractions for communicating with the peripherals and some compatibility with other products in the vendor’s product line. The Embedded Rust community took a slightly different approach to this problem with the embedded-hal project which provides a set of centrally defined traits to build an ecosystem of platform-agnostic drivers.

By adopting embedded-hal for our luna-soc design, we’ve made it possible for other luna-soc users to easily target their own custom designs even if the underlying peripheral implementations differ. It also means the Moondancer firmware can be more easily ported to any other platform with an embedded-hal implementation.

smolusb

Given that Facedancer requires direct access to the USB peripheral to perform emulation, and our SoC only has 64 kilobytes of RAM, we’ve developed ‘smolusb’, a new lightweight device-side USB stack that provides:

  • a set of traits for implementing HAL USB device drivers
  • data structures for defining device descriptors
  • data structures for defining class and vendor requests
  • device enumeration support

‘smolusb’ does not require Rust alloc support, uses a single statically allocated buffer for read operations, and supports zero-copy write operations. It supports high-level operations such as device enumeration but also provides several “escape hatches” that allow for direct control of the underlying peripheral for the purposes of device emulation and other Facedancer features.

Moondancer firmware and backend

Moondancer manages the communication between the Facedancer library and the remotely controlled USB peripheral and is split into two components:

  1. Moondancer firmware written in Rust and running in the SoC on Cynthion. The Moondancer firmware implements the Facedancer command set and controls Cynthion’s USB ports.
  2. Moondancer backend written in Python and running on the host. The Moondancer backend handles all communication between Facedancer and the Moondancer firmware.

To mediate communication between the Moondancer backend and the Moondancer firmware we’ve used a Rust implementation of the same libgreat RPC protocol used by GreatFET and other Great Scott Gadgets open-source projects. The power of libgreat is its ability to generate and expose simple explorable APIs via Python, allowing for flexible communications between computers and embedded devices, embedded drivers, and more without having to get into the murky details of driver development, transports or serialization protocols. We hope this design decision will also allow others to more easily develop and integrate their own custom firmware for embedded USB applications with host software!

On the host side, the Moondancer backend is responsible for translating calls from Facedancer into libgreat commands which are then received on Cynthion’s CONTROL USB port, deserialized by libgreat and forwarded to the Moondancer firmware which is responsible for operating the Cynthion’s TARGET USB port.

Finally, the Moondancer firmware implements the Moondancer API for directly controlling the USB peripheral via operations to manage port connections, reset the bus, set the device address, manage endpoints, and send/receive data packets.

Wrapping up

If you have access to Cynthion hardware and would like to try out Moondancer please feel free to check out the Cynthion repository. Also, if you’re interested in custom SoC development and Embedded Rust, you can check out the luna-soc repository. Most of the non-USB functionality has also been tested on other ECP5 devices so, with a little bit of luck, you might be able to get something going with your favorite development board.

Acknowledgements

We would like to express our sincere gratitude to two individuals without whom Moondancer would not have been possible.

In particular, our work builds on the research of Travis Goodspeed who developed the original Facedancer board and software, and Kate Temkin who extended the software and generalized it for other platforms.

You can learn more about the history of Facedancer and LUNA in our fifth Crowd Supply update: “The History of LUNA”.


Great Scott Gadgets is now on Mastodon

Great Scott Gadgets is on Mastodon! You’ll get a lot of the same information as you get on our other social media profiles, but if Mastodon is your platform preference, we now have you covered.

GSG on Mastodon


Free Stuff - July 2023

The July recipient for the Great Scott Gadgets Free Stuff Program is Joona. Joona plans to use the YARD Stick One we are sending him to develop and test radios. He will be writing documentation and creating tutorials on his projects.


Cynthion Delivery Timeline Update

Note: This is a crosspost of a Cynthion update on Crowd Supply: https://www.crowdsupply.com/great-scott-gadgets/cynthion/updates/cynthion-delivery-timeline-update

Hello, campaign backers and other supporters of Cynthion and Great Scott Gadgets! In this update, we hoped to tell you that manufacturing was in progress and that we were getting close to delivering the first Cynthions to you. Unfortunately, we have encountered more delays while getting the hardware ready to go to manufacturing.

The first delay was caused by another component availability barrier, which is now solved. After our last hardware update, we placed an order with our contract manufacturer for the additional components added to the Cynthion hardware design in r0.6. At the time of engineering r0.6, all of the new components added in this major revision were widely available, and we had no indications that there would be issues acquiring them. However, when we received the BOM quote for these additional components from our contract manufacturer, we learned that the power monitor part we had planned to use, PAC1954T-E/J6CX, was no longer in stock, and the quoted lead time was 20 weeks. Focused on getting the product delivered to you on time, we ordered a substitute part right away, and our engineering team immediately got to work on another hardware revision to instead use a PAC1954 package that was in stock, PAC1954T-E/4MX. This revision was relatively minor, but we did have to order another round of prototypes for verification and testing. Each time we order and test a new round of prototypes, the process takes 3-4 weeks. We named this new Cynthion revision r1.1.0 and went to an independent test lab for the necessary pre-compliance testing before ordering the production PCBs.

Before going to manufacturing or putting Cynthion on the market, we must certify that the final product conforms with applicable regulations and standards in all the countries we will be shipping to. One of the important standards Cynthion must comply with is electromagnetic compatibility (EMC). Cynthion’s compliance with EMC includes two components: emissions and immunity. Emissions compliance means that the Cynthion won’t emit electromagnetic interference (EMI) that can adversely affect other devices in its environment, and immunity compliance ensures that the Cynthion itself won’t be affected by electrostatic discharge (ESD). So far, we have had two rounds of testing in an independent EMC testing lab, each evaluating Cynthion on the emissions and immunity standards we’ve identified as applicable to Cynthion. In the first round of testing, Cynthion passed neither emissions nor immunity tests. By the second round, a couple of weeks later, the engineering team had solved the immunity problems, and Cynthion passed with flying colors– no such luck with the emissions portion of the test.

Since then, we have worked very hard to solve the EMC emissions issues with Cynthion. The engineering team identified software and gateware modifications that significantly reduced emissions and also found some small hardware changes that helped. Although great progress was made in a short period of time, it became apparent that a new hardware revision (r1.2.0) would be required to test modifications that we think will clear the final hurdle. As of today, we are waiting for another round of prototypes to be delivered so that we can test the new revision, and we hope that these will be the pre-manufacturing prototypes that will successfully pass EMC at the lab.

Although it is only possible to precisely estimate when Cynthion will ship once we have solved the emissions issues and manufacturing is underway, you will see that the expected delivery date for Cynthion fulfillment has changed to January 31st, 2024, which is our best estimate. In this new proposed timeline, we allow ourselves another month to resolve the EMC emissions issues and pass pre-compliance testing. After that, we estimate that manufacturing and quality control testing will take about three months, and we are allowing another two months for logistics and fulfillment. We will have a better idea of whether this timeline is realistic or not after the next round of EMC pre-compliance testing at the independent lab, and we will be sure to update you again if things change again with the timeline. In the meantime, we assure you that delivering Cynthion to you is our priority, and thank you for your patience as we continue to work hard to accomplish this goal we have been working towards for so long. Please accept our apologies for not updating you as often as we’d like to. The engineers who are best equipped to write these updates are very busy working on getting Cynthion to you as soon as possible!


Free Stuff - June 2023

The June recipient for the Great Scott Gadgets Free Stuff Program is Daniel. Dan is planning to use the HackRF One we are sending him to run workshops in his school and with his amateur radio group. He will also be creating videos with his new HackRF One on his YouTube channel “Radio Dan ZL2DTL”. Please welcome Radio Dan to the software-defined radio community!


Free Stuff - May 2023

The May recipient for the Great Scott Gadgets Free Stuff Program is the UCLA IEEE Wireless, RF, and Analog Project (WRAP). Participants in this club have the opportunity to learn hands-on radio engineering skills by designing, building, and testing a 2-way radio system capable of operating in the 100s of MHz. Through this project, students can learn digital and analog radio techniques like implementing filters and a mixer from discrete diodes and using coils for up/downconversion. WRAP asked for a HackRF One to aid in debugging wireless links, where they will use the HackRF One both as a modulated waveform generator for receiver testing and a real-time spectrum analyzer for transmitter and device debugging. We really look forward to seeing their end projects.


subscribe to GSG feed