blob: 4b0349c3d32ee178ce4b181f4f5c4c1ef61cc831 [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
8bool DMAEdgeCounter::ExtractValue(const DMASample &sample) {
9 if (inverted_) {
10 return !sample.Get(input_);
11 } else {
12 return sample.Get(input_);
13 }
14}
15
16void DMAEdgeCounter::UpdateFromSample(const DMASample &sample) {
17 if (!have_prev_sample_) {
18 have_prev_sample_ = true;
19 } else {
20 if (!ExtractValue(prev_sample_) && ExtractValue(sample)) {
21 pos_edge_count_++;
22 pos_edge_time_ = sample.GetTimestamp();
23 pos_last_encoder_ = sample.GetRaw(encoder_);
24 } else if (ExtractValue(prev_sample_) && !ExtractValue(sample)) {
25 neg_edge_count_++;
26 neg_edge_time_ = sample.GetTimestamp();
27 neg_last_encoder_ = sample.GetRaw(encoder_);
28 }
29 }
30
31 prev_sample_ = sample;
32}
33
34void DMASynchronizer::CheckDMA() {
35 DMASample current_sample;
36
37 size_t remaining = 0;
38 while (true) {
39 switch (dma_->Read(&current_sample, 0, &remaining)) {
40 case DMA::STATUS_OK:
41 for (auto &c : handlers_) {
42 c->UpdateFromSample(current_sample);
43 }
44
45 if (remaining == 0) {
46 if (sample_time_ < current_sample.GetTimestamp()) {
47 // If the latest DMA sample happened after we started polling, then
48 // just use the values from it because they're more recent.
49 for (auto &c : handlers_) {
50 c->PollFromSample(current_sample);
51 }
52 }
53 return;
54 }
55 case DMA::STATUS_TIMEOUT:
56 return;
57 case DMA::STATUS_ERROR:
58 LOG(WARNING, "DMA read failed\n");
59 break;
60 }
61 }
62}
63
64} // namespace wpilib
65} // namespace frc971