blob: 102d12b10f9cf73760277a3ea90619d6d3e82877 [file] [log] [blame]
Brian Silvermanff7b3472015-01-26 17:53:04 -05001#include "frc971/wpilib/dma_edge_counting.h"
2
3#include "aos/common/logging/logging.h"
4
5namespace frc971 {
6namespace wpilib {
7
Brian Silverman552350b2015-08-02 18:23:34 -07008bool DMAEdgeCounter::ExtractValue(const DMASample &sample) const {
Brian Silverman03a00cf2015-08-29 19:26:54 -07009 return sample.Get(input_);
Brian Silvermanff7b3472015-01-26 17:53:04 -050010}
11
12void DMAEdgeCounter::UpdateFromSample(const DMASample &sample) {
Brian Silverman03a00cf2015-08-29 19:26:54 -070013 const bool previous_value =
14 have_prev_sample_ ? ExtractValue(prev_sample_) : polled_value_;
15 have_prev_sample_ = true;
Brian Silvermanff7b3472015-01-26 17:53:04 -050016 prev_sample_ = sample;
Brian Silverman03a00cf2015-08-29 19:26:54 -070017
18 if (!previous_value && ExtractValue(sample)) {
19 pos_edge_count_++;
20 pos_edge_time_ = sample.GetTimestamp();
21 pos_last_encoder_ = sample.GetRaw(encoder_);
22 } else if (previous_value && !ExtractValue(sample)) {
23 neg_edge_count_++;
24 neg_edge_time_ = sample.GetTimestamp();
25 neg_last_encoder_ = sample.GetRaw(encoder_);
26 }
Brian Silvermanff7b3472015-01-26 17:53:04 -050027}
28
29void DMASynchronizer::CheckDMA() {
30 DMASample current_sample;
31
32 size_t remaining = 0;
33 while (true) {
34 switch (dma_->Read(&current_sample, 0, &remaining)) {
35 case DMA::STATUS_OK:
36 for (auto &c : handlers_) {
37 c->UpdateFromSample(current_sample);
38 }
39
40 if (remaining == 0) {
41 if (sample_time_ < current_sample.GetTimestamp()) {
42 // If the latest DMA sample happened after we started polling, then
43 // just use the values from it because they're more recent.
44 for (auto &c : handlers_) {
45 c->PollFromSample(current_sample);
46 }
47 }
48 return;
49 }
50 case DMA::STATUS_TIMEOUT:
51 return;
52 case DMA::STATUS_ERROR:
53 LOG(WARNING, "DMA read failed\n");
54 break;
55 }
56 }
57}
58
59} // namespace wpilib
60} // namespace frc971