blob: 9a7232caf2cd659ff756fb20913bf0fdf30d2cb7 [file] [log] [blame]
Brian Silverman4aa83042018-01-05 12:47:31 -08001#ifndef MOTORS_USB_INTERRUPT_OUT_H_
2#define MOTORS_USB_INTERRUPT_OUT_H_
3
4#include "motors/usb/usb.h"
5#include "motors/util.h"
6
7#include <array>
8#include <string>
9
10namespace frc971 {
11namespace teensy {
12
13// A simple function that just has an interrupt out endpoint and exposes the
14// data received.
15class InterruptOut final : public UsbFunction {
16 public:
17 static constexpr size_t kSize = 64;
18
19 InterruptOut(UsbDevice *device, const ::std::string &name)
20 : UsbFunction(device), name_(name) {}
21 ~InterruptOut() override = default;
22
23 // Copies the next packet into buffer.
24 // buffer must have kSize of space available.
25 // Returns the size of the packet, or -1 if there isn't one.
26 int ReceiveData(char *buffer);
27
28 private:
29 void Initialize() override;
30
31 void HandleOutFinished(int endpoint, BdtEntry *bdt_entry) override;
32 void HandleConfigured(int endpoint) override;
33 void HandleReset() override {
34 device()->SetBdtEntry(endpoint_, Direction::kRx, EvenOdd::kEven,
35 {0, nullptr});
36 device()->SetBdtEntry(endpoint_, Direction::kRx, EvenOdd::kOdd,
37 {0, nullptr});
38 }
39
40 ::std::string MicrosoftExtendedCompatibleId() override {
41 ::std::string result = "WINUSB";
42 result.resize(16);
43 return result;
44 }
45
46 ::std::array<::std::array<char, kSize>, 2> buffers_;
47
48 int interface_;
49 int endpoint_;
50
51 // These are BdtEntries which we're holding onto until the data is copied out.
52 // This also has the advantage of avoiding any more data being sent until
53 // we're ready.
54 // They are only manipulated with interrupts disabled.
55 BdtEntry *first_rx_held_ = nullptr, *second_rx_held_ = nullptr;
56 Data01 next_rx_toggle_;
57
58 const ::std::string name_;
59};
60
61} // namespace teensy
62} // namespace frc971
63
64#endif // MOTORS_USB_INTERRUPT_OUT_H_