blob: 8864116f1c3caf2fcf9a1dc5009a8dd4d20be5e8 [file] [log] [blame]
Brian Silvermanff7b3472015-01-26 17:53:04 -05001#include "frc971/wpilib/dma_edge_counting.h"
2
John Park33858a32018-09-28 23:05:48 -07003#include "aos/logging/logging.h"
Brian Silvermanff7b3472015-01-26 17:53:04 -05004
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) {
milind-u6b672f82023-02-24 17:36:27 -080028 if (have_prev_sample_ && high_time_ != 0 && prev_sample_.Get(input_) &&
29 !sample.Get(input_)) {
30 last_width_ = (sample.GetTime() - high_time_) * 0.000001;
31 } else if (have_prev_sample_ && !prev_sample_.Get(input_) &&
32 sample.Get(input_)) {
33 high_time_ = prev_sample_.GetTime();
Austin Schuh8e5950d2018-03-21 20:29:40 -070034 }
35 have_prev_sample_ = true;
36 prev_sample_ = sample;
37}
38
Ravago Jones128a50e2021-09-18 15:19:39 -070039void DMAPulseSeparationReader::UpdateFromSample(const DMASample &sample) {
Austin Schuh6c053ef2021-09-26 14:32:16 -070040 // save the time of the falling edge of the input one
41 if (have_prev_sample_ && !sample.Get(input_one_) &&
42 prev_sample_.Get(input_one_)) {
Ravago Jones128a50e2021-09-18 15:19:39 -070043 input_one_time_ = sample.GetTimestamp();
44 }
45
Austin Schuh6c053ef2021-09-26 14:32:16 -070046 // take the difference in time between the falling edge of the input one and
47 // the falling edge of the input two
48 if (!sample.Get(input_two_) && input_one_time_.has_value()) {
Ravago Jones128a50e2021-09-18 15:19:39 -070049 last_width_ = sample.GetTimestamp() - input_one_time_.value();
50 pulses_detected_++;
51 input_one_time_.reset();
52 }
Austin Schuh6c053ef2021-09-26 14:32:16 -070053
54 have_prev_sample_ = true;
55 prev_sample_ = sample;
Ravago Jones128a50e2021-09-18 15:19:39 -070056}
57
Brian Silvermanff7b3472015-01-26 17:53:04 -050058void DMASynchronizer::CheckDMA() {
59 DMASample current_sample;
60
61 size_t remaining = 0;
62 while (true) {
63 switch (dma_->Read(&current_sample, 0, &remaining)) {
64 case DMA::STATUS_OK:
65 for (auto &c : handlers_) {
66 c->UpdateFromSample(current_sample);
67 }
68
69 if (remaining == 0) {
Austin Schuhf853bde2017-11-23 13:23:27 -080070 if (sample_time_ < static_cast<int64_t>(current_sample.GetTime())) {
Brian Silvermanff7b3472015-01-26 17:53:04 -050071 // If the latest DMA sample happened after we started polling, then
72 // just use the values from it because they're more recent.
73 for (auto &c : handlers_) {
74 c->PollFromSample(current_sample);
75 }
76 }
77 return;
78 }
Austin Schuh8e5950d2018-03-21 20:29:40 -070079 break;
Brian Silvermanff7b3472015-01-26 17:53:04 -050080 case DMA::STATUS_TIMEOUT:
81 return;
82 case DMA::STATUS_ERROR:
Austin Schuhf257f3c2019-10-27 21:00:43 -070083 AOS_LOG(WARNING, "DMA read failed\n");
Brian Silvermanff7b3472015-01-26 17:53:04 -050084 break;
85 }
86 }
87}
88
89} // namespace wpilib
90} // namespace frc971