blob: 96409b072fadc8676b2feb9f28388cca6eae6fd4 [file] [log] [blame]
#ifndef MOTORS_USB_INTERRUPT_OUT_H_
#define MOTORS_USB_INTERRUPT_OUT_H_
#include <array>
#include <string>
#include "motors/usb/usb.h"
#include "motors/util.h"
namespace frc971::teensy {
// A simple function that just has an interrupt out endpoint and exposes the
// data received.
class InterruptOut final : public UsbFunction {
public:
static constexpr size_t kSize = 64;
InterruptOut(UsbDevice *device, const ::std::string &name)
: UsbFunction(device), name_(name) {}
~InterruptOut() override = default;
// Copies the next packet into buffer.
// buffer must have kSize of space available.
// Returns the size of the packet, or -1 if there isn't one.
int ReceiveData(char *buffer);
private:
void Initialize() override;
void HandleOutFinished(int endpoint, BdtEntry *bdt_entry) override;
void HandleConfigured(int endpoint) override;
void HandleReset() override {
device()->SetBdtEntry(endpoint_, Direction::kRx, EvenOdd::kEven,
{0, nullptr});
device()->SetBdtEntry(endpoint_, Direction::kRx, EvenOdd::kOdd,
{0, nullptr});
}
::std::string MicrosoftExtendedCompatibleId() override {
::std::string result = "WINUSB";
result.resize(16);
return result;
}
::std::array<::std::array<char, kSize>, 2> buffers_;
int interface_;
int endpoint_;
// These are BdtEntries which we're holding onto until the data is copied out.
// This also has the advantage of avoiding any more data being sent until
// we're ready.
// They are only manipulated with interrupts disabled.
BdtEntry *first_rx_held_ = nullptr, *second_rx_held_ = nullptr;
Data01 next_rx_toggle_;
const ::std::string name_;
};
} // namespace frc971::teensy
#endif // MOTORS_USB_INTERRUPT_OUT_H_