When it comes to capturing data and ensuring our applications/devices are getting the most accurate values, they often fall short because of how we tend to use averages to correct for drift and the inherent inaccuracies in our sensors. As an alternative to this approach, Signaloid's platform of both cloud and hardware-level integrations aims to track these uncertainties at the CPU architecture-level rather than as an external set of application libraries. Their C0-microSD FPGA board is able to perform these functions in the form of a coprocessor to a traditional microcontroller. And beyond uncertainty tracking, the board allows for custom bitstreams to be loaded onto the iCE40 FPGA from a host computer's SD card slot thanks to its bootloader.
One of the biggest strengths of the C0-microSD is its ultra-compact micro SD form-factor which can interface directly with host devices, the carrier board, or even GPIO pins connected to a micro SD breakout module. The card itself contains a Lattice iCE40UP5K FPGA featuring 5280 logic cells, 120Kb of dual-port Block RAM, and 1Mb of single-port RAM. Non-volatile data can be stored in the on-board 128Mb (16MB) flash IC courtesy of a Renesas AT25QL128A IC.
Lastly, there are two LEDs for indicating status, six GPIO pins that are accessible from the micro SD card's contacts, and an additional five pins available from the test pads.
The SD-Dev carrier boardIn addition to the C0-microSD, Signaloid has produced a carrier board called the SD-Dev which is a compact way to access all of the available I/O over a plethora of connectors. The carrier has a connector underneath for attaching a Raspberry Pi Compute Module 4 for easy, direct communication with the C0-microSD. It features a total of four USB-C ports, with two for downstream connections, one solely for power, and the last one that carries both data and power from a host device. The SD-Dev also includes ports for Micro HDMI, I2C, and SPI, as well as both full-size and micro SD card slots.
Although the C0-microSD comes preloaded with Signaloid's RISC-V processor core bitstream, it can also act as a standalone device with the full capabilities of the iCE40UP5K FPGA. When slotted into a host computer as a micro SD card, the board will present itself as an unformatted drive, thus allowing other applications to upload custom bitstreams to what appears as a mounted disk. When powered externally and without an SD host present, the C0-microSD's built-in bootloader will attempt to load the latest bitstream from storage into the FPGA automatically.
To get started with the C0-microSD as an FPGA (not using the C0 Processor RISC-V core yet), we first need to install a toolchain for compiling and loading bitstreams. Head to the OSS CAD Suite repository from YosysHQ, navigate to the releases page, and follow the installation instructions for your host device's operating system/architecture. In the end, there should be a bin
folder accessible from the current user's path.
The code for this project is found in this repository. Clone it before navigating to the inner /verilog/blink
directory where you'll find a Makefile, pin constraints, and a verilog file that specifies the circuit being configured. In this case, it specifies the two status LEDs, a clock, and a counter that helps to periodically flip the LEDs' states. Compile the bitstream binary by running make
.
Plugging in the C0-microSD opens a new disk dialog, and after dismissing without formatting the drive, its path can be verified by running lsblk
on Linux and ensuring the disk appears with a 20.2MB capacity. Lastly, run:
make program DEVICE=<path>
to load the new bitstream into the C0-microSD. Unplug the board, give it external power, and watch as the red and green LEDs enter into an alternating blink pattern.
Building off the previous example, this demonstration showcases how the C0-microSD's I/O can be directly accessed through its exposed contacts for both LED outputs and button inputs. Simply connect one pushbutton switch between SD_DATA2/GND
and another between SD_DATA3/GND
. Then compile and upload the bitstream using the same method as the previous section from inside the verilog/breathe-button
directory. The red and green LEDs at the top of the C0-microSD should begin to breathe in an alternating pattern while allowing for the breathing rate to be adjusted via the pair of buttons.
The verilog file starts by declaring a clock source and several registers for storing the iCE40's built-in LED controller's configuration. Unlike a typical ARM CPU core which would require setting a timer, interrupts, and a counter for controlling the duty cycle of an output pin, the LED driver allows the setting of delays, breathing ramp times, and brightness levels through its addressable registers, which in turn, can drive external pins.
The LED breathing speed can be continuously adjusted via the two buttons connected to the SD DATA2
and SD DATA3
pins that have been pulled high internally. When started, the system enters into a finite-state machine (FSM) that initializes the LED driver and begins breathing the LEDs. From here, it waits until a debounced button press has been detected, and depending on which one, will either increment or decrement the breathing rate by modifying the driver's Breathe On
and Breathe Off
control registers.
Given its compact size, ease-of-use, and open-source nature, the C0-microSD is a great platform for developing and deploying custom bitstreams to its iCE40 FPGA over the SD protocol. The source code for both example projects and additional documentation can be found in this repository from Signaloid.
Comments