diff --git a/motors/usb/cdc.cc b/motors/usb/cdc.cc
new file mode 100644
index 0000000..b082750
--- /dev/null
+++ b/motors/usb/cdc.cc
@@ -0,0 +1,426 @@
+#include "motors/usb/cdc.h"
+
+#include <string.h>
+
+#define CHECK(c)                             \
+  do {                                       \
+    if (!(c)) {                              \
+      while (true) {                         \
+        for (int i = 0; i < 10000000; ++i) { \
+          GPIOC_PSOR = 1 << 5;               \
+        }                                    \
+        for (int i = 0; i < 10000000; ++i) { \
+          GPIOC_PCOR = 1 << 5;               \
+        }                                    \
+      }                                      \
+    }                                        \
+  } while (false)
+
+namespace frc971 {
+namespace teensy {
+namespace {
+
+// Aka the Communications Device Class code, the Communications Class code,
+// and the Communications Interface Class code.
+constexpr uint8_t communications_class() { return 0x02; }
+constexpr uint8_t data_interface_class() { return 0x0A; }
+
+namespace cdc_descriptor_subtype {
+constexpr uint8_t header() { return 0x00; }
+constexpr uint8_t header_length() { return 5; }
+constexpr uint8_t call_management() { return 0x01; }
+constexpr uint8_t call_management_length() { return 5; }
+constexpr uint8_t abstract_control_management() { return 0x02; }
+constexpr uint8_t abstract_control_management_length() { return 4; }
+constexpr uint8_t direct_line_management() { return 0x03; }
+constexpr uint8_t telephone_ringer() { return 0x04; }
+constexpr uint8_t telephone_call_etc() { return 0x05; }
+// Can't just call this "union" because that's a keyword...
+constexpr uint8_t union_function() { return 0x06; }
+constexpr uint8_t union_length(int number_subordinates) {
+  return 4 + number_subordinates;
+}
+constexpr uint8_t country_selection() { return 0x07; }
+constexpr uint8_t telephone_operational_modes() { return 0x08; }
+constexpr uint8_t usb_terminal() { return 0x09; }
+constexpr uint8_t network_channel() { return 0x0A; }
+constexpr uint8_t protocol_unit() { return 0x0B; }
+constexpr uint8_t extension_unit() { return 0x0C; }
+constexpr uint8_t multichannel_management() { return 0x0D; }
+constexpr uint8_t capi_control() { return 0x0E; }
+constexpr uint8_t ethernet_networking() { return 0x0F; }
+constexpr uint8_t atm_networking() { return 0x10; }
+constexpr uint8_t wireless_handset_control() { return 0x11; }
+constexpr uint8_t mobile_direct_line() { return 0x12; }
+constexpr uint8_t mdlm_detail() { return 0x13; }
+constexpr uint8_t device_management() { return 0x14; }
+constexpr uint8_t obex() { return 0x15; }
+constexpr uint8_t command_set() { return 0x16; }
+constexpr uint8_t command_set_detail() { return 0x17; }
+constexpr uint8_t telephone_control() { return 0x18; }
+constexpr uint8_t obex_service() { return 0x19; }
+constexpr uint8_t ncm() { return 0x1A; }
+}  // namespace cdc_descriptor_subtype
+
+namespace communications_subclass {
+constexpr uint8_t direct_line_control_model() { return 0x01; }
+constexpr uint8_t abstract_control_model() { return 0x02; }
+constexpr uint8_t telephone_control_model() { return 0x03; }
+constexpr uint8_t multichannel_control_model() { return 0x04; }
+constexpr uint8_t capi_control_model() { return 0x05; }
+constexpr uint8_t ethernet_networking_control_model() { return 0x06; }
+constexpr uint8_t atm_networking_control_model() { return 0x07; }
+constexpr uint8_t wireless_handset_control_model() { return 0x08; }
+constexpr uint8_t device_management() { return 0x09; }
+constexpr uint8_t mobile_direct_line_model() { return 0x0A; }
+constexpr uint8_t obex() { return 0x0B; }
+constexpr uint8_t ethernet_emulation_model() { return 0x0C; }
+constexpr uint8_t network_control_model() { return 0x0D; }
+}  // namespace communications_subclass
+
+namespace cdc_class_requests {
+constexpr uint8_t send_encapsulated_command() { return 0x00; }
+constexpr uint8_t get_encapsulated_response() { return 0x01; }
+constexpr uint8_t set_comm_feature() { return 0x02; }
+constexpr uint8_t get_comm_feature() { return 0x03; }
+constexpr uint8_t clear_comm_feature() { return 0x04; }
+constexpr uint8_t set_aux_line_state() { return 0x10; }
+constexpr uint8_t set_hook_state() { return 0x11; }
+constexpr uint8_t pulse_setup() { return 0x12; }
+constexpr uint8_t send_pulse() { return 0x13; }
+constexpr uint8_t set_pulse_time() { return 0x14; }
+constexpr uint8_t ring_aux_jack() { return 0x15; }
+constexpr uint8_t set_line_coding() { return 0x20; }
+constexpr uint8_t get_line_coding() { return 0x21; }
+constexpr uint8_t set_control_line_state() { return 0x22; }
+constexpr uint8_t send_break() { return 0x23; }
+constexpr uint8_t set_ringer_parms() { return 0x30; }
+constexpr uint8_t get_ringer_parms() { return 0x31; }
+constexpr uint8_t set_operation_parms() { return 0x32; }
+constexpr uint8_t get_operation_parms() { return 0x33; }
+constexpr uint8_t set_line_parms() { return 0x34; }
+constexpr uint8_t get_line_parms() { return 0x35; }
+constexpr uint8_t dial_digits() { return 0x36; }
+constexpr uint8_t set_unit_parameter() { return 0x37; }
+constexpr uint8_t get_unit_parameter() { return 0x38; }
+constexpr uint8_t clear_unit_parameter() { return 0x39; }
+constexpr uint8_t get_profile() { return 0x3A; }
+}  // namespace cdc_class_requests
+
+}  // namespace
+
+void AcmTty::Initialize() {
+  status_interface_ = AddInterface();
+  data_interface_ = AddInterface();
+  status_endpoint_ = AddEndpoint();
+  data_tx_endpoint_ = AddEndpoint();
+  data_rx_endpoint_ = AddEndpoint();
+
+  {
+    const auto iad_descriptor = CreateDescriptor(
+        iad_descriptor_length(), UsbDescriptorType::kInterfaceAssociation);
+    iad_descriptor->AddByte(status_interface_);       // bFirstInterface
+    iad_descriptor->AddByte(2);                       // bInterfaceCount
+    iad_descriptor->AddByte(communications_class());  // bFunctionClass
+    iad_descriptor->AddByte(communications_subclass::
+                                abstract_control_model());  // bFunctionSubClass
+    iad_descriptor->AddByte(0);                             // bFunctionProtocol
+    iad_descriptor->AddByte(device()->AddString("UsbTty"));  // iFunction
+  }
+
+  {
+    const auto interface_descriptor = CreateDescriptor(
+        interface_descriptor_length(), UsbDescriptorType::kInterface);
+    interface_descriptor->AddByte(status_interface_);  // bInterfaceNumber
+    interface_descriptor->AddByte(0);  // bAlternateSetting
+    interface_descriptor->AddByte(1);                       // bNumEndpoints
+    interface_descriptor->AddByte(communications_class());  // bInterfaceClass
+    interface_descriptor->AddByte(
+        communications_subclass::
+            abstract_control_model());  // bInterfaceSubClass
+    interface_descriptor->AddByte(0);   // bInterfaceProtocol
+    interface_descriptor->AddByte(
+        device()->AddString("UsbTty.status"));  // iInterface
+  }
+
+  {
+    const auto cdc_header =
+        CreateDescriptor(cdc_descriptor_subtype::header_length(),
+                         UsbClassDescriptorType::kInterface);
+    cdc_header->AddByte(
+        cdc_descriptor_subtype::header());  // bDescriptorSubtype
+    cdc_header->AddUint16(0x0110);          // bcdCDC
+  }
+
+  {
+    const auto call_management =
+        CreateDescriptor(cdc_descriptor_subtype::call_management_length(),
+                         UsbClassDescriptorType::kInterface);
+    call_management->AddByte(
+        cdc_descriptor_subtype::call_management());  // bDescriptorSubtype
+    // We don't do call management.
+    call_management->AddByte(0);  // bmCapabilities
+    call_management->AddByte(data_interface_);  // bDataInterface
+  }
+
+  {
+    const auto abstract_control_management =
+        CreateDescriptor(cdc_descriptor_subtype::abstract_control_management_length(),
+                         UsbClassDescriptorType::kInterface);
+    abstract_control_management->AddByte(
+        cdc_descriptor_subtype::abstract_control_management());  // bDescriptorSubtype
+    // We support:
+    //   line_coding and serial_state
+    //   send_break
+    // We don't support:
+    //   comm_feature
+    //   network_notification
+    abstract_control_management->AddByte(6);  // bmCapabilities
+  }
+
+  {
+    const auto cdc_union_descriptor =
+        CreateDescriptor(cdc_descriptor_subtype::union_length(1),
+                         UsbClassDescriptorType::kInterface);
+    cdc_union_descriptor->AddByte(
+        cdc_descriptor_subtype::union_function());     // bDescriptorSubtype
+    cdc_union_descriptor->AddByte(status_interface_);  // bMasterInterface
+    cdc_union_descriptor->AddByte(data_interface_);  // bSlaveInterface
+  }
+
+  {
+    const auto endpoint_descriptor = CreateDescriptor(
+        endpoint_descriptor_length(), UsbDescriptorType::kEndpoint);
+    endpoint_descriptor->AddByte(status_endpoint_ |
+                                 m_endpoint_address_in());  // bEndpointAddress
+    endpoint_descriptor->AddByte(
+        m_endpoint_attributes_interrupt());                // bmAttributes
+    endpoint_descriptor->AddUint16(kStatusMaxPacketSize);  // wMaxEndpointSize
+    // Set it to the max because we have nothing to send, so no point using bus
+    // bandwidth asking.
+    endpoint_descriptor->AddByte(255);  // bInterval
+  }
+
+  {
+    const auto interface_descriptor = CreateDescriptor(
+        interface_descriptor_length(), UsbDescriptorType::kInterface);
+    interface_descriptor->AddByte(data_interface_);         // bInterfaceNumber
+    interface_descriptor->AddByte(0);                       // bAlternateSetting
+    interface_descriptor->AddByte(2);                       // bNumEndpoints
+    interface_descriptor->AddByte(data_interface_class());  // bInterfaceClass
+    interface_descriptor->AddByte(0);  // bInterfaceSubClass
+    interface_descriptor->AddByte(0);  // bInterfaceProtocol
+    interface_descriptor->AddByte(
+        device()->AddString("UsbTty.data"));  // iInterface
+  }
+
+  // Kernel seems to think tx and rx belong in the other order, but it deals
+  // with either one. Everybody's examples seem to use this order, and the
+  // kernel deals with it, so going to go with this.
+  {
+    const auto endpoint_descriptor = CreateDescriptor(
+        endpoint_descriptor_length(), UsbDescriptorType::kEndpoint);
+    endpoint_descriptor->AddByte(data_rx_endpoint_);  // bEndpointAddress
+    endpoint_descriptor->AddByte(m_endpoint_attributes_bulk());  // bmAttributes
+    endpoint_descriptor->AddUint16(kDataMaxPacketSize);  // wMaxEndpointSize
+    endpoint_descriptor->AddByte(1);                     // bInterval
+  }
+
+  {
+    const auto endpoint_descriptor = CreateDescriptor(
+        endpoint_descriptor_length(), UsbDescriptorType::kEndpoint);
+    endpoint_descriptor->AddByte(data_tx_endpoint_ |
+                                 m_endpoint_address_in());  // bEndpointAddress
+    endpoint_descriptor->AddByte(m_endpoint_attributes_bulk());  // bmAttributes
+    endpoint_descriptor->AddUint16(kDataMaxPacketSize);  // wMaxEndpointSize
+    endpoint_descriptor->AddByte(1);                     // bInterval
+  }
+}
+
+// We deliberately don't implement SendEncapsulatedCommand and
+// GetEncapsulatedResponse because there doesn't seem to be any reason for
+// anybody to send those to us, despite them being "required".
+UsbFunction::SetupResponse AcmTty::HandleEndpoint0SetupPacket(
+    const UsbDevice::SetupPacket &setup_packet) {
+  if (G_SETUP_REQUEST_TYPE_TYPE(setup_packet.request_type) !=
+      SetupRequestType::kClass) {
+    return SetupResponse::kIgnored;
+  }
+  if (G_SETUP_REQUEST_TYPE_RECIPIENT(setup_packet.request_type) !=
+      standard_setup_recipients::kInterface) {
+    return SetupResponse::kIgnored;
+  }
+  if (setup_packet.index != status_interface_) {
+    return SetupResponse::kIgnored;
+  }
+  const bool in = setup_packet.request_type & M_SETUP_REQUEST_TYPE_IN;
+  switch (setup_packet.request) {
+    case cdc_class_requests::set_line_coding():
+      if (in || setup_packet.value != 0 ||
+          setup_packet.length != sizeof(line_coding_)) {
+        return SetupResponse::kStall;
+      }
+      next_endpoint0_out_ = NextEndpoint0Out::kLineCoding;
+      return SetupResponse::kHandled;
+
+    case cdc_class_requests::get_line_coding():
+      if (!in || setup_packet.value != 0 ||
+          setup_packet.length != sizeof(line_coding_)) {
+        return SetupResponse::kStall;
+      }
+      line_coding_to_send_ = line_coding_;
+      device()->QueueEndpoint0Data(
+          reinterpret_cast<const char *>(&line_coding_to_send_),
+          setup_packet.length);
+      return SetupResponse::kHandled;
+
+    case cdc_class_requests::set_control_line_state():
+      if (in || setup_packet.length != 0) {
+        return SetupResponse::kStall;
+      }
+      control_line_state_ = setup_packet.value;
+      device()->SendEmptyEndpoint0Packet();
+      return SetupResponse::kHandled;
+
+    case cdc_class_requests::send_break():
+      if (in || setup_packet.length != 0) {
+        return SetupResponse::kStall;
+      }
+      // TODO(Brian): setup_packet.value is the length of the break in ms.
+      // 0xFFFF means keep sending break until receiving another one.
+      device()->SendEmptyEndpoint0Packet();
+      return SetupResponse::kHandled;
+  }
+  return SetupResponse::kStall;
+}
+
+UsbFunction::SetupResponse AcmTty::HandleEndpoint0OutPacket(void *data,
+                                                            int data_length) {
+  switch (next_endpoint0_out_) {
+    case NextEndpoint0Out::kNone:
+      return SetupResponse::kIgnored;
+
+    case NextEndpoint0Out::kLineCoding:
+      if (data_length != sizeof(line_coding_)) {
+        return SetupResponse::kStall;
+      }
+      memcpy(&line_coding_, data, data_length);
+      device()->SendEmptyEndpoint0Packet();
+      return SetupResponse::kHandled;
+
+    default:
+      return SetupResponse::kIgnored;
+  }
+}
+
+void AcmTty::HandleOutFinished(int endpoint, BdtEntry *bdt_entry) {
+  if (endpoint == data_rx_endpoint_) {
+    const size_t data_size = G_USB_BD_BC(bdt_entry->buffer_descriptor);
+    CHECK(rx_queue_.Write(static_cast<char *>(bdt_entry->address), data_size) ==
+          data_size);
+    dma_memory_barrier();
+
+    DisableInterrupts disable_interrupts;
+    // If we don't have space to handle it, don't return the entry so we'll
+    // ask the host to wait to transmit more data.
+    if (rx_queue_.space_available() >= kDataMaxPacketSize * 2) {
+      bdt_entry->buffer_descriptor = M_USB_BD_OWN | M_USB_BD_DTS |
+                                     V_USB_BD_BC(kDataMaxPacketSize) |
+                                     static_cast<uint32_t>(next_rx_toggle_);
+      next_rx_toggle_ = Data01Inverse(next_rx_toggle_);
+    } else {
+      if (first_rx_held_ == nullptr) {
+        first_rx_held_ = bdt_entry;
+      } else {
+        CHECK(second_rx_held_ == nullptr);
+        second_rx_held_ = bdt_entry;
+      }
+    }
+  }
+}
+
+void AcmTty::HandleInFinished(int endpoint, BdtEntry * /*bdt_entry*/,
+                              EvenOdd odd) {
+  if (endpoint == data_tx_endpoint_) {
+    DisableInterrupts disable_interrupts;
+    CHECK(odd == BufferStateToEmpty(tx_state_));
+    tx_state_ = BufferStateAfterEmpty(tx_state_);
+    EnqueueTxData(disable_interrupts);
+  }
+}
+
+void AcmTty::HandleConfigured(int endpoint) {
+  // TODO(Brian): Handle data already in the buffers correctly.
+  if (endpoint == status_endpoint_) {
+    device()->ConfigureEndpointFor(status_endpoint_, false, true, true);
+  } else if (endpoint == data_tx_endpoint_) {
+    device()->ConfigureEndpointFor(data_tx_endpoint_, false, true, true);
+    next_tx_toggle_ = Data01::kData0;
+    DisableInterrupts disable_interrupts;
+    EnqueueTxData(disable_interrupts);
+  } else if (endpoint == data_rx_endpoint_) {
+    device()->ConfigureEndpointFor(data_rx_endpoint_, true, false, true);
+    next_rx_toggle_ = Data01::kData0;
+    device()->SetBdtEntry(
+        data_rx_endpoint_, Direction::kRx, EvenOdd::kEven,
+        {M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(tx_buffers_[0].size()),
+         tx_buffers_[0].data()});
+    device()->SetBdtEntry(
+        data_rx_endpoint_, Direction::kRx, EvenOdd::kOdd,
+        {M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(tx_buffers_[1].size()) |
+             M_USB_BD_DATA1,
+         tx_buffers_[1].data()});
+  }
+}
+
+size_t AcmTty::Read(void *buffer, size_t buffer_size) {
+  const size_t r = rx_queue_.Read(static_cast<char *>(buffer), buffer_size);
+
+  DisableInterrupts disable_interrupts;
+  if (rx_queue_.space_available() >= kDataMaxPacketSize * 2) {
+    if (first_rx_held_ != nullptr) {
+      first_rx_held_->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kDataMaxPacketSize) |
+          static_cast<uint32_t>(next_rx_toggle_);
+      next_rx_toggle_ = Data01Inverse(next_rx_toggle_);
+    }
+    if (second_rx_held_ != nullptr) {
+      second_rx_held_->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kDataMaxPacketSize) |
+          static_cast<uint32_t>(next_rx_toggle_);
+      next_rx_toggle_ = Data01Inverse(next_rx_toggle_);
+    }
+    first_rx_held_ = second_rx_held_ = nullptr;
+  }
+
+  return r;
+}
+
+size_t AcmTty::Write(const void *buffer, size_t buffer_size) {
+  const size_t r =
+      tx_queue_.Write(static_cast<const char *>(buffer), buffer_size);
+  DisableInterrupts disable_interrupts;
+  EnqueueTxData(disable_interrupts);
+  return r;
+}
+
+// TODO(Brian): Could this critical section be broken up per buffer we fill?
+void AcmTty::EnqueueTxData(const DisableInterrupts &) {
+  while (BufferStateHasEmpty(tx_state_) && !tx_queue_.empty()) {
+    const EvenOdd next_tx_odd = BufferStateToFill(tx_state_);
+    const size_t buffer_size =
+        tx_queue_.Read(tx_buffer_for(next_tx_odd), kDataMaxPacketSize);
+    CHECK(buffer_size > 0);
+    dma_memory_barrier();
+    device()->SetBdtEntry(
+        data_tx_endpoint_, Direction::kTx, next_tx_odd,
+        {M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(buffer_size) |
+             static_cast<uint32_t>(next_tx_toggle_),
+         tx_buffer_for(next_tx_odd)});
+    tx_state_ = BufferStateAfterFill(tx_state_);
+    next_tx_toggle_ = Data01Inverse(next_tx_toggle_);
+  }
+}
+
+}  // namespace teensy
+}  // namespace frc971
