blob: 8ea307131f7985fec36cbc2185ce93302ec0cd06 [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 =
Austin Schuhf83da152017-03-05 22:28:45 -080014 have_prev_sample_ ? ExtractValue(prev_sample_) : previous_polled_value_;
Brian Silverman03a00cf2015-08-29 19:26:54 -070015 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_++;
Brian Silverman03a00cf2015-08-29 19:26:54 -070020 pos_last_encoder_ = sample.GetRaw(encoder_);
21 } else if (previous_value && !ExtractValue(sample)) {
22 neg_edge_count_++;
Brian Silverman03a00cf2015-08-29 19:26:54 -070023 neg_last_encoder_ = sample.GetRaw(encoder_);
24 }
Brian Silvermanff7b3472015-01-26 17:53:04 -050025}
26
Austin Schuh8e5950d2018-03-21 20:29:40 -070027void DMAPulseWidthReader::UpdateFromSample(const DMASample &sample) {
28 if (have_prev_sample_ && prev_sample_.Get(input_) && !sample.Get(input_)) {
29 last_width_ = sample.GetTimestamp() - prev_sample_.GetTimestamp();
30 }
31 have_prev_sample_ = true;
32 prev_sample_ = sample;
33}
34
Brian Silvermanff7b3472015-01-26 17:53:04 -050035void DMASynchronizer::CheckDMA() {
36 DMASample current_sample;
37
38 size_t remaining = 0;
39 while (true) {
40 switch (dma_->Read(&current_sample, 0, &remaining)) {
41 case DMA::STATUS_OK:
42 for (auto &c : handlers_) {
43 c->UpdateFromSample(current_sample);
44 }
45
46 if (remaining == 0) {
Austin Schuhf853bde2017-11-23 13:23:27 -080047 if (sample_time_ < static_cast<int64_t>(current_sample.GetTime())) {
Brian Silvermanff7b3472015-01-26 17:53:04 -050048 // If the latest DMA sample happened after we started polling, then
49 // just use the values from it because they're more recent.
50 for (auto &c : handlers_) {
51 c->PollFromSample(current_sample);
52 }
53 }
54 return;
55 }
Austin Schuh8e5950d2018-03-21 20:29:40 -070056 break;
Brian Silvermanff7b3472015-01-26 17:53:04 -050057 case DMA::STATUS_TIMEOUT:
58 return;
59 case DMA::STATUS_ERROR:
60 LOG(WARNING, "DMA read failed\n");
61 break;
62 }
63 }
64}
65
66} // namespace wpilib
67} // namespace frc971