Skip to content

majbthrd/D21eem

Repository files navigation

USB CDC-EEM example for SAMD21

Inspired by lrndis, this is a CDC-EEM implementation for the Atmel/Microchip SAMD21. It leverages a variant of the SAMDx1 USB stack from vcp.

As with lrndis, lwIP is utilized to provide a rudimentary TCP/IP stack, DHCP server, and web server.

This is closely related to D21rndis, a RNDIS implementation, and D21ecm, a CDC-ECM implementation. All implementations share most of the same code, differing only in the driver.

Usage

Due to the high memory usage of TCP/IP, a SAMD21 with 32kBytes of RAM and at least 128kBytes of FLASH is needed. Development was done with the SAMD21 Xplained Pro (ATSAMD21J18), but the SparkFun SAMD21 Mini Breakout (ATSAMD21G18) and Arduino Zero (ATSAMD21G18) ought to also be feasible.

Specifics

Look at the ./project/app.c to get an idea of how the code could be modified. As written, one quantity (systick) is shown in real-time as "Device Time" on the embedded web server (192.168.7.1) and another three quantities (alpha, bravo, and charlie) are "User Controls" on the web page that cause app.c code to be executed.

Arduino Zero Boards with Problems

This code normally uses the USBCRM mode of the SAMD21. In this mode, the part disciplines its own 48MHz RC clock using the USB SOF messages. The advantage of this is simple: it doesn't require optional external components.

Until buying a PCB from Sparkfun, I have had zero issues with USBCRM across several hardware designs. However, the Sparkfun design (derived from Arduino Zero) uses a 32k external crystal and USB will NOT work reliably on it unless this optional crystal is used as the timing source. Furthermore, the Arduino Zero bootloader source code depends on a 32k external crystal without any explanation as to why. There is no verbiage in the datasheet to indicate special requirements for USBCRM. AT07175 (the SAM-BA app note that served as a basis for the "Arduino Zero" bootloader) makes no special requirements. There are no errata notes on possible scenarios where USBCRM should not function.

The USBCRM mode should be universal, as it doesn't depend on optional external components. For that reason, the source code uses this mode by default. However, the source code now has an "#if 1" that can be changed to "#if 0" to cause the optional external 32k crystal (if populated on your design) to be used instead of USBCRM.

Requirements for compiling

Rowley Crossworks for ARM is presently needed to compile this code. The project file is under ./ide/Rowley/.

All the code is gcc/clang compatible, and as time permits, other options may be added.