Merge "Work around bug in the SPI driver"
diff --git a/frc971/wpilib/ADIS16448.cc b/frc971/wpilib/ADIS16448.cc
index e539828..043d15f 100644
--- a/frc971/wpilib/ADIS16448.cc
+++ b/frc971/wpilib/ADIS16448.cc
@@ -22,6 +22,7 @@
 
 template <uint8_t size>
 bool ADIS16448::DoTransaction(uint8_t to_send[size], uint8_t to_receive[size]) {
+  rx_clearer_.ClearRxFifo();
   switch (spi_->Transaction(to_send, to_receive, size)) {
     case -1:
       LOG(INFO, "SPI::Transaction of %zd bytes failed\n", size);
diff --git a/frc971/wpilib/ADIS16448.h b/frc971/wpilib/ADIS16448.h
index 4f2aaa0..52090a1 100644
--- a/frc971/wpilib/ADIS16448.h
+++ b/frc971/wpilib/ADIS16448.h
@@ -12,6 +12,7 @@
 #undef ERROR
 
 #include "aos/common/logging/logging.h"
+#include "frc971/wpilib/spi_rx_clearer.h"
 
 namespace frc971 {
 namespace wpilib {
@@ -95,6 +96,8 @@
   double gyro_x_zeroed_offset_ = 0.0;
   double gyro_y_zeroed_offset_ = 0.0;
   double gyro_z_zeroed_offset_ = 0.0;
+
+  SpiRxClearer rx_clearer_;
 };
 
 }  // namespace wpilib
diff --git a/frc971/wpilib/BUILD b/frc971/wpilib/BUILD
index 1119286..ae9d10a 100644
--- a/frc971/wpilib/BUILD
+++ b/frc971/wpilib/BUILD
@@ -1,264 +1,278 @@
-package(default_visibility = ['//visibility:public'])
+package(default_visibility = ["//visibility:public"])
 
-load('//aos/build:queues.bzl', 'queue_library')
+load("//aos/build:queues.bzl", "queue_library")
 
 queue_library(
-  name = 'logging_queue',
-  srcs = [
-    'logging.q',
-  ],
+    name = "logging_queue",
+    srcs = [
+        "logging.q",
+    ],
 )
 
 cc_library(
-  name = 'encoder_and_potentiometer',
-  srcs = [
-    'encoder_and_potentiometer.cc',
-  ],
-  hdrs = [
-    'encoder_and_potentiometer.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-    ':dma_edge_counting',
-    '//aos/linux_code:init',
-    '//aos/common/logging',
-    '//aos/common:mutex',
-    ':dma',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "encoder_and_potentiometer",
+    srcs = [
+        "encoder_and_potentiometer.cc",
+    ],
+    hdrs = [
+        "encoder_and_potentiometer.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":dma",
+        ":dma_edge_counting",
+        "//aos/common:mutex",
+        "//aos/common/logging",
+        "//aos/linux_code:init",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'dma_edge_counting',
-  srcs = [
-    'dma_edge_counting.cc',
-  ],
-  hdrs = [
-    'dma_edge_counting.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-    '//aos/common/logging',
-    ':dma',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "dma_edge_counting",
+    srcs = [
+        "dma_edge_counting.cc",
+    ],
+    hdrs = [
+        "dma_edge_counting.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":dma",
+        "//aos/common/logging",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'interrupt_edge_counting',
-  srcs = [
-    'interrupt_edge_counting.cc',
-  ],
-  hdrs = [
-    'interrupt_edge_counting.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-    '//aos/common/logging',
-    '//aos/common:stl_mutex',
-    '//aos/common:time',
-    '//aos/linux_code:init',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "interrupt_edge_counting",
+    srcs = [
+        "interrupt_edge_counting.cc",
+    ],
+    hdrs = [
+        "interrupt_edge_counting.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//aos/linux_code:init",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'buffered_pcm',
-  srcs = [
-    'buffered_solenoid.cc',
-    'buffered_pcm.cc',
-  ],
-  hdrs = [
-    'buffered_solenoid.h',
-    'buffered_pcm.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-    '//aos/common/logging',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "buffered_pcm",
+    srcs = [
+        "buffered_pcm.cc",
+        "buffered_solenoid.cc",
+    ],
+    hdrs = [
+        "buffered_pcm.h",
+        "buffered_solenoid.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common/logging",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'gyro_interface',
-  srcs = [
-    'gyro_interface.cc',
-  ],
-  hdrs = [
-    'gyro_interface.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-    '//aos/common/logging',
-    '//aos/common:time',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "gyro_interface",
+    srcs = [
+        "gyro_interface.cc",
+    ],
+    hdrs = [
+        "gyro_interface.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'gyro_sender',
-  srcs = [
-    'gyro_sender.cc',
-  ],
-  hdrs = [
-    'gyro_sender.h',
-  ],
-  deps = [
-    ':gyro_interface',
-    '//frc971/queues:gyro',
-    '//frc971/zeroing:averager',
-    '//aos/common/logging',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/util:phased_loop',
-    '//aos/common/messages:robot_state',
-    '//aos/linux_code:init',
-    '//aos/common:time',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "gyro_sender",
+    srcs = [
+        "gyro_sender.cc",
+    ],
+    hdrs = [
+        "gyro_sender.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":gyro_interface",
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:phased_loop",
+        "//aos/linux_code:init",
+        "//frc971/queues:gyro",
+        "//frc971/zeroing:averager",
+    ],
 )
 
 cc_library(
-  name = 'lpd8806',
-  srcs = [
-    'LPD8806.cc',
-  ],
-  hdrs = [
-    'LPD8806.h',
-  ],
-  deps = [
-    '//aos/common:mutex',
-    '//third_party:wpilib',
-    '//frc971/queues:gyro',
-    '//aos/common:time',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "lpd8806",
+    srcs = [
+        "LPD8806.cc",
+    ],
+    hdrs = [
+        "LPD8806.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common:mutex",
+        "//aos/common:time",
+        "//frc971/queues:gyro",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'loop_output_handler',
-  srcs = [
-    'loop_output_handler.cc',
-  ],
-  hdrs = [
-    'loop_output_handler.h',
-  ],
-  deps = [
-    '//aos/common:scoped_fd',
-    '//aos/linux_code:init',
-    '//aos/common:time',
-    '//aos/common/util:log_interval',
-    '//aos/common/messages:robot_state',
-  ],
+    name = "loop_output_handler",
+    srcs = [
+        "loop_output_handler.cc",
+    ],
+    hdrs = [
+        "loop_output_handler.h",
+    ],
+    deps = [
+        "//aos/common:scoped_fd",
+        "//aos/common:time",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/linux_code:init",
+    ],
 )
 
 cc_library(
-  name = 'joystick_sender',
-  srcs = [
-    'joystick_sender.cc',
-  ],
-  hdrs = [
-    'joystick_sender.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-    '//aos/common/messages:robot_state',
-    '//aos/linux_code:init',
-    '//aos/common/network:team_number',
-    '//aos/common/logging:queue_logging',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "joystick_sender",
+    srcs = [
+        "joystick_sender.cc",
+    ],
+    hdrs = [
+        "joystick_sender.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/network:team_number",
+        "//aos/linux_code:init",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  hdrs = [
-    'wpilib_interface.h',
-  ],
-  deps = [
-    '//aos/common/messages:robot_state',
-    '//third_party:wpilib',
-    '//aos/common/logging:queue_logging',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    hdrs = [
+        "wpilib_interface.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//third_party:wpilib",
+    ],
 )
 
 queue_library(
-  name = 'pdp_values',
-  srcs = [
-    'pdp_values.q',
-  ],
+    name = "pdp_values",
+    srcs = [
+        "pdp_values.q",
+    ],
 )
 
 cc_library(
-  name = 'pdp_fetcher',
-  srcs = [
-    'pdp_fetcher.cc',
-  ],
-  hdrs = [
-    'pdp_fetcher.h',
-  ],
-  deps = [
-    ':pdp_values',
-    '//third_party:wpilib',
-    '//aos/common/logging:queue_logging',
-    '//aos/linux_code:init',
-    '//aos/common/util:phased_loop',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "pdp_fetcher",
+    srcs = [
+        "pdp_fetcher.cc",
+    ],
+    hdrs = [
+        "pdp_fetcher.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":pdp_values",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/util:phased_loop",
+        "//aos/linux_code:init",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'wpilib_robot_base',
-  hdrs = [
-    'wpilib_robot_base.h',
-  ],
-  deps = [
-    '//third_party:wpilib',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_robot_base",
+    hdrs = [
+        "wpilib_robot_base.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//third_party:wpilib",
+    ],
 )
 
 queue_library(
-  name = 'imu_queue',
-  srcs = [
-    'imu.q',
-  ],
+    name = "imu_queue",
+    srcs = [
+        "imu.q",
+    ],
 )
 
 cc_library(
-  name = 'ADIS16448',
-  hdrs = [
-    'ADIS16448.h',
-  ],
-  srcs = [
-    'ADIS16448.cc',
-  ],
-  deps = [
-    ':imu_queue',
-    '//aos/common/logging',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common:time',
-    '//aos/linux_code:init',
-    '//frc971/zeroing:averager',
-    '//third_party:wpilib',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "ADIS16448",
+    srcs = [
+        "ADIS16448.cc",
+    ],
+    hdrs = [
+        "ADIS16448.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":imu_queue",
+        ":spi_rx_clearer",
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/linux_code:init",
+        "//frc971/zeroing:averager",
+        "//third_party:wpilib",
+    ],
 )
 
 cc_library(
-  name = 'dma',
-  hdrs = [
-    'dma.h',
-  ],
-  srcs = [
-    'dma.cc',
-  ],
-  deps = [
-    '//third_party:wpilib',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "dma",
+    srcs = [
+        "dma.cc",
+    ],
+    hdrs = [
+        "dma.h",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//third_party:wpilib",
+    ],
+)
+
+cc_library(
+    name = "spi_rx_clearer",
+    srcs = [
+        "spi_rx_clearer.cc",
+    ],
+    hdrs = [
+        "spi_rx_clearer.h",
+    ],
+    deps = [
+        "//aos/common/logging",
+    ],
 )
diff --git a/frc971/wpilib/spi_rx_clearer.cc b/frc971/wpilib/spi_rx_clearer.cc
new file mode 100644
index 0000000..fda8d7c
--- /dev/null
+++ b/frc971/wpilib/spi_rx_clearer.cc
@@ -0,0 +1,43 @@
+#include "frc971/wpilib/spi_rx_clearer.h"
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "aos/common/logging/logging.h"
+
+namespace frc971 {
+namespace wpilib {
+
+SpiRxClearer::SpiRxClearer() {
+  const int fd = PCHECK(open("/dev/mem", O_RDWR));
+  void *const mmap_result = mmap(nullptr, kMappingSize, PROT_READ | PROT_WRITE,
+                                 MAP_SHARED, fd, spi_peripheral_base_);
+  if (mmap_result == MAP_FAILED) {
+    PLOG(FATAL, "mmap the SPI peripheral from /dev/mem failed\n");
+  }
+  PCHECK(close(fd));
+  mapping_ = static_cast<volatile uint32_t *>(mmap_result);
+}
+
+SpiRxClearer::~SpiRxClearer() {
+  PCHECK(munmap(const_cast<uint32_t *>(mapping_), kMappingSize));
+}
+
+void SpiRxClearer::ClearRxFifo() {
+  // The FIFO has 128 entries, so if we do that many reads and don't get it all,
+  // something weird is going on.
+  for (int i = 0; i < 128; ++i) {
+    if (RxFifoIsEmpty()) {
+      // If there's nothing more, we're done.
+      return;
+    }
+    // Read the next byte.
+    LOG(DEBUG, "Read from RX FIFO: %" PRIx32 "\n", ReadRegister(0x20));
+  }
+  LOG(FATAL, "Failed to clear the RX FIFO\n");
+}
+
+}  // namespace wpilib
+}  // namespace frc971
diff --git a/frc971/wpilib/spi_rx_clearer.h b/frc971/wpilib/spi_rx_clearer.h
new file mode 100644
index 0000000..17936ab
--- /dev/null
+++ b/frc971/wpilib/spi_rx_clearer.h
@@ -0,0 +1,41 @@
+#ifndef FRC971_WPILIB_SPI_RX_CLEARER_H_
+#define FRC971_WPILIB_SPI_RX_CLEARER_H_
+
+#include <stdint.h>
+
+namespace frc971 {
+namespace wpilib {
+
+// Allows clearing the RX FIFO of the roboRIO's SPI peripheral on demand. This
+// is necessary to work around a driver bug. See
+// https://docs.google.com/document/d/1ANV4LtnVcku2fk84Y31pIIqrxUD_x_dYyCQgp10NB0k/edit
+// for details.
+class SpiRxClearer {
+ public:
+  SpiRxClearer();
+  ~SpiRxClearer();
+
+  // Actually clears the RX FIFO. This should be very fast. Don't do this while
+  // any operations via the kernel driver are ongoing.
+  void ClearRxFifo();
+
+ private:
+  // How big of a mapping we do.
+  static constexpr uint32_t kMappingSize = 0x1000;
+
+  // The physical base address of the SPI instance we're going to mess with.
+  const uint32_t spi_peripheral_base_ = 0xe0006000;
+  volatile uint32_t *mapping_;
+
+  uint32_t ReadRegister(uint32_t offset) { return mapping_[offset / 4]; }
+  void WriteRegister(uint32_t offset, uint32_t value) {
+    mapping_[offset / 4] = value;
+  }
+
+  bool RxFifoIsEmpty() { return !(ReadRegister(4) & (1 << 4)); }
+};
+
+}  // namespace wpilib
+}  // namespace frc971
+
+#endif // FRC971_WPILIB_SPI_RX_CLEARER_H_
diff --git a/y2016/wpilib_interface.cc b/y2016/wpilib_interface.cc
index 9bf2b0e..2f37bcb 100644
--- a/y2016/wpilib_interface.cc
+++ b/y2016/wpilib_interface.cc
@@ -724,6 +724,7 @@
     reader.set_dma(make_unique<DMA>());
     ::std::thread reader_thread(::std::ref(reader));
 
+    // TODO(Brian): This interacts poorly with the SpiRxClearer in ADIS16448.
     ::frc971::wpilib::GyroSender gyro_sender;
     ::std::thread gyro_thread(::std::ref(gyro_sender));
 
diff --git a/y2017_bot3/BUILD b/y2017_bot3/BUILD
index 5f952ac..f2992cf 100644
--- a/y2017_bot3/BUILD
+++ b/y2017_bot3/BUILD
@@ -1,91 +1,90 @@
-load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load("//aos/downloader:downloader.bzl", "aos_downloader")
 
 cc_binary(
-  name = 'joystick_reader',
-  srcs = [
-    'joystick_reader.cc',
-  ],
-  deps = [
-    '//aos/common/actions:action_lib',
-    '//aos/common/logging',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/input:drivetrain_input',
-    '//aos/input:joystick_input',
-    '//aos/linux_code:init',
-    '//frc971/autonomous:auto_queue',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/autonomous:base_autonomous_actor',
-    '//y2017_bot3/control_loops/drivetrain:drivetrain_base',
-    '//y2017_bot3/control_loops/superstructure:superstructure_queue',
-    '//y2017_bot3/control_loops/superstructure:superstructure_lib',
-  ],
+    name = "joystick_reader",
+    srcs = [
+        "joystick_reader.cc",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/actions:action_lib",
+        "//aos/common/logging",
+        "//aos/common/util:log_interval",
+        "//aos/input:drivetrain_input",
+        "//aos/input:joystick_input",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/autonomous:base_autonomous_actor",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//y2017_bot3/control_loops/drivetrain:drivetrain_base",
+        "//y2017_bot3/control_loops/superstructure:superstructure_lib",
+        "//y2017_bot3/control_loops/superstructure:superstructure_queue",
+    ],
 )
 
 cc_binary(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  deps = [
-    '//aos/common/controls:control_loop',
-    '//aos/common/logging',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:log_interval',
-    '//aos/common/util:phased_loop',
-    '//aos/common:math',
-    '//aos/common:stl_mutex',
-    '//aos/common:time',
-    '//aos/linux_code:init',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/control_loops:queues',
-    '//frc971/wpilib:ADIS16448',
-    '//frc971/wpilib:buffered_pcm',
-    '//frc971/wpilib:dma',
-    '//frc971/wpilib:dma_edge_counting',
-    '//frc971/wpilib:encoder_and_potentiometer',
-    '//frc971/wpilib:gyro_sender',
-    '//frc971/wpilib:interrupt_edge_counting',
-    '//frc971/wpilib:joystick_sender',
-    '//frc971/wpilib:logging_queue',
-    '//frc971/wpilib:loop_output_handler',
-    '//frc971/wpilib:pdp_fetcher',
-    '//frc971/wpilib:wpilib_interface',
-    '//frc971/wpilib:wpilib_robot_base',
-    '//third_party:wpilib',
-    '//y2017_bot3/control_loops/drivetrain:polydrivetrain_plants',
-    '//y2017_bot3/control_loops/superstructure:superstructure_queue',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common:math",
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/controls:control_loop",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/common/util:phased_loop",
+        "//aos/linux_code:init",
+        "//frc971/control_loops:queues",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/wpilib:buffered_pcm",
+        "//frc971/wpilib:dma",
+        "//frc971/wpilib:dma_edge_counting",
+        "//frc971/wpilib:encoder_and_potentiometer",
+        "//frc971/wpilib:gyro_sender",
+        "//frc971/wpilib:interrupt_edge_counting",
+        "//frc971/wpilib:joystick_sender",
+        "//frc971/wpilib:logging_queue",
+        "//frc971/wpilib:loop_output_handler",
+        "//frc971/wpilib:pdp_fetcher",
+        "//frc971/wpilib:wpilib_interface",
+        "//frc971/wpilib:wpilib_robot_base",
+        "//third_party:wpilib",
+        "//y2017_bot3/control_loops/drivetrain:polydrivetrain_plants",
+        "//y2017_bot3/control_loops/superstructure:superstructure_queue",
+    ],
 )
 
 aos_downloader(
-  name = 'download',
-  start_srcs = [
-    ':wpilib_interface',
-    ':joystick_reader',
-    '//aos:prime_start_binaries',
-    '//y2017_bot3/control_loops/drivetrain:drivetrain',
-    '//y2017_bot3/control_loops/superstructure:superstructure',
-  ],
-  srcs = [
-    '//aos:prime_binaries',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download",
+    srcs = [
+        "//aos:prime_binaries",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":wpilib_interface",
+        ":joystick_reader",
+        "//aos:prime_start_binaries",
+        "//y2017_bot3/control_loops/drivetrain:drivetrain",
+        "//y2017_bot3/control_loops/superstructure:superstructure",
+    ],
 )
 
 aos_downloader(
-  name = 'download_stripped',
-  start_srcs = [
-    ':wpilib_interface.stripped',
-    ':joystick_reader.stripped',
-    '//aos:prime_start_binaries_stripped',
-    '//y2017_bot3/control_loops/drivetrain:drivetrain.stripped',
-    '//y2017_bot3/control_loops/superstructure:superstructure.stripped',
-  ],
-  srcs = [
-    '//aos:prime_binaries_stripped',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download_stripped",
+    srcs = [
+        "//aos:prime_binaries_stripped",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":wpilib_interface.stripped",
+        ":joystick_reader.stripped",
+        "//aos:prime_start_binaries_stripped",
+        "//y2017_bot3/control_loops/drivetrain:drivetrain.stripped",
+        "//y2017_bot3/control_loops/superstructure:superstructure.stripped",
+    ],
 )
diff --git a/y2017_bot3/wpilib_interface.cc b/y2017_bot3/wpilib_interface.cc
index f9457ce..c337035 100644
--- a/y2017_bot3/wpilib_interface.cc
+++ b/y2017_bot3/wpilib_interface.cc
@@ -31,7 +31,6 @@
 
 #include "frc971/control_loops/control_loops.q.h"
 #include "frc971/control_loops/drivetrain/drivetrain.q.h"
-#include "frc971/wpilib/ADIS16448.h"
 #include "frc971/wpilib/buffered_pcm.h"
 #include "frc971/wpilib/buffered_solenoid.h"
 #include "frc971/wpilib/gyro_sender.h"
diff --git a/y2018/BUILD b/y2018/BUILD
index 6606233..ee81842 100644
--- a/y2018/BUILD
+++ b/y2018/BUILD
@@ -102,7 +102,6 @@
         "//frc971/wpilib:dma",
         "//frc971/wpilib:dma_edge_counting",
         "//frc971/wpilib:encoder_and_potentiometer",
-        "//frc971/wpilib:gyro_sender",
         "//frc971/wpilib:interrupt_edge_counting",
         "//frc971/wpilib:joystick_sender",
         "//frc971/wpilib:logging_queue",
diff --git a/y2018/wpilib_interface.cc b/y2018/wpilib_interface.cc
index aa13298..b43f421 100644
--- a/y2018/wpilib_interface.cc
+++ b/y2018/wpilib_interface.cc
@@ -41,7 +41,6 @@
 #include "frc971/wpilib/dma.h"
 #include "frc971/wpilib/dma_edge_counting.h"
 #include "frc971/wpilib/encoder_and_potentiometer.h"
-#include "frc971/wpilib/gyro_sender.h"
 #include "frc971/wpilib/interrupt_edge_counting.h"
 #include "frc971/wpilib/joystick_sender.h"
 #include "frc971/wpilib/logging.q.h"
@@ -838,9 +837,6 @@
     imu.set_reset(imu_reset.get());
     ::std::thread imu_thread(::std::ref(imu));
 
-    ::frc971::wpilib::GyroSender gyro_sender;
-    ::std::thread gyro_thread(::std::ref(gyro_sender));
-
     // While as of 2/9/18 the drivetrain Victors are SPX, it appears as though
     // they are identical, as far as DrivetrainWriter is concerned, to the SP
     // variety so all the Victors are written as SPs.
@@ -903,9 +899,6 @@
     imu.Quit();
     imu_thread.join();
 
-    gyro_sender.Quit();
-    gyro_thread.join();
-
     drivetrain_writer.Quit();
     drivetrain_writer_thread.join();
     superstructure_writer.Quit();