blob: 0baf473a199166ff987a1c6c8ae1bc3e4bd9e0b2 [file] [log] [blame]
Brian Silverman2aa83d72015-01-24 18:03:11 -05001#ifndef _DMA_H_
2#define _DMA_H_
3
4#include <stdint.h>
5
6#include <array>
7#include <memory>
8
9#include "ChipObject.h"
10#include "DigitalSource.h"
11#include "Encoder.h"
12
13class DMA;
14
15class DMASample {
16 public:
17 DMASample() {}
18
19 // Returns the FPGA timestamp of the sample.
20 double GetTimestamp() const;
21
22 // All Get methods either return the requested value, or set the Error.
23
24 // Returns the value of the digital input in the sample.
25 bool Get(DigitalSource *input) const;
26 // Returns the raw value of the encoder in the sample.
27 int32_t GetRaw(Encoder *input) const;
28 // Returns the {1, 2, or 4} X scaled value of the encoder in the sample.
29 int32_t Get(Encoder *input) const;
30
31 private:
32 friend DMA;
33
34 // Returns the offset of the sample type in the buffer, or -1 if it isn't in
35 // the sample.
36 ssize_t offset(int index) const;
37
38 // TODO(austin): This should be re-used from WPILib... Once I merge this back
39 // into WPILib.
40
41 DMA *dma_;
42 uint32_t read_buffer_[64];
43};
44
45class DMA : public ErrorBase {
46 public:
47 DMA();
48 virtual ~DMA();
49
50 // Sets whether or not DMA is paused.
51 void SetPause(bool pause);
52
53 // Sets the number of triggers that need to occur before a sample is saved.
54 void SetRate(uint32_t cycles);
55
56 // Adds the input signal to the state to snapshot on the trigger event.
57 // Call Add() and SetExternalTrigger() before Start().
58 void Add(Encoder *encoder);
59 void Add(DigitalSource *input);
60
61 // Configures DMA to trigger on an external trigger. There can only be 4
62 // external triggers.
63 // Call Add() and SetExternalTrigger() before Start().
64 void SetExternalTrigger(DigitalSource *input, bool rising, bool falling);
65
66 // Starts reading samples into the buffer. Clears all previous samples before
67 // starting.
68 // Call Start() before Read().
69 void Start(size_t queue_depth);
70
71 enum ReadStatus {
72 STATUS_OK = 0,
73 STATUS_TIMEOUT = 1,
74 STATUS_ERROR = 2,
75 };
76
77 // Reads a sample from the DMA buffer, waiting up to timeout_ms for it.
78 // Returns a status code indicating whether the read worked, timed out, or
79 // failed.
80 // Call Add() and SetExternalTrigger() then Start() before Read().
81 // The sample is only usable while this DMA object is left started.
82 ReadStatus Read(DMASample *sample, uint32_t timeout_ms, size_t *remaining);
83
84 private:
85 ::std::unique_ptr<nFPGA::tDMAManager> manager_; // set by Start()
86 typedef nFPGA::nRoboRIO_FPGANamespace::tDMA tDMA;
87 friend DMASample;
88
89 // The offsets into the sample structure for each DMA type, or -1 if it isn't
90 // in the set of values.
91 ssize_t channel_offsets_[18];
92
93 // The size of the data to read to get a sample.
94 size_t capture_size_ = 0;
95 tDMA::tConfig tconfig_;
96 tDMA *tdma_config_;
97
98 ::std::array<bool, 4> trigger_channels_ = {{false, false, false, false}};
99};
100
101#endif // _DMA_H_