Add DMA lidar lite reader.

Change-Id: I8195ff2331029adcdb961b9925f43471cc6b08f9
diff --git a/frc971/wpilib/dma_edge_counting.cc b/frc971/wpilib/dma_edge_counting.cc
index 4cf4440..8ea3071 100644
--- a/frc971/wpilib/dma_edge_counting.cc
+++ b/frc971/wpilib/dma_edge_counting.cc
@@ -24,6 +24,14 @@
   }
 }
 
+void DMAPulseWidthReader::UpdateFromSample(const DMASample &sample) {
+  if (have_prev_sample_ && prev_sample_.Get(input_) && !sample.Get(input_)) {
+    last_width_ = sample.GetTimestamp() - prev_sample_.GetTimestamp();
+  }
+  have_prev_sample_ = true;
+  prev_sample_ = sample;
+}
+
 void DMASynchronizer::CheckDMA() {
   DMASample current_sample;
 
@@ -45,6 +53,7 @@
           }
           return;
         }
+        break;
       case DMA::STATUS_TIMEOUT:
         return;
       case DMA::STATUS_ERROR:
diff --git a/frc971/wpilib/dma_edge_counting.h b/frc971/wpilib/dma_edge_counting.h
index 813f59c..c8a00ea 100644
--- a/frc971/wpilib/dma_edge_counting.h
+++ b/frc971/wpilib/dma_edge_counting.h
@@ -37,6 +37,38 @@
   virtual void AddToDMA(DMA *dma) = 0;
 };
 
+// TODO(brian): Timeout old data.
+class DMAPulseWidthReader : public DMASampleHandlerInterface {
+ public:
+  DMAPulseWidthReader(DigitalInput *input) : input_(input) {}
+  DMAPulseWidthReader() = default;
+
+  void set_input(DigitalInput *input) { input_ = input; }
+
+  double last_width() const { return last_width_; }
+
+ private:
+  void UpdateFromSample(const DMASample & /*sample*/) override;
+  void UpdatePolledValue() override {}
+
+  void PollFromSample(const DMASample & /*sample*/) override {}
+  void AddToDMA(DMA *dma) override {
+    dma->Add(input_);
+    dma->SetExternalTrigger(input_, true, true);
+  }
+
+  DigitalInput *input_ = nullptr;
+
+  // The last DMA reading we got.
+  DMASample prev_sample_;
+  // Whether or not we actually have anything in prev_sample_.
+  bool have_prev_sample_ = false;
+
+  double last_width_ = ::std::numeric_limits<double>::quiet_NaN();
+
+  DISALLOW_COPY_AND_ASSIGN(DMAPulseWidthReader);
+};
+
 // Counts edges on a sensor using DMA data and latches encoder values
 // corresponding to those edges.
 class DMAEdgeCounter : public DMASampleHandlerInterface {