Clean up printing in MCU code and add new options
We now have four different ways of getting debug prints off of boards,
with varying tradeoffs. Split out the printing into dedicated libraries
that are easy to switch between to avoid duplicating even more code, and
also make using the new options easy.
USB is handy for testing the code on a Teensy.
Semihosting is nice in theory, but in practice it's super slow and
messes up the code's timing.
ITM works well, as long as you have a debugger attached.
Serial also works pretty well, but it means having another cable.
Change-Id: I7af5099d421c33f0324aeca92b46732e341848d4
diff --git a/motors/print/usb.h b/motors/print/usb.h
new file mode 100644
index 0000000..7e63184
--- /dev/null
+++ b/motors/print/usb.h
@@ -0,0 +1,62 @@
+#ifndef MOTORS_PRINT_USB_H_
+#define MOTORS_PRINT_USB_H_
+
+#include "motors/print/print.h"
+#include "motors/usb/cdc.h"
+#include "motors/usb/usb.h"
+
+namespace frc971 {
+namespace motors {
+
+// A printing implementation which uses externally-created functions. The stdout
+// one is required, while the debug one is optional.
+class UsbPrinting final : public PrintingImplementation {
+ public:
+ UsbPrinting(teensy::AcmTty *stdout_tty, teensy::AcmTty *debug_tty);
+ ~UsbPrinting() override;
+
+ void Initialize() override;
+
+ int WriteStdout(gsl::span<const char> buffer) override {
+ return stdout_tty_->Write(buffer.data(), buffer.size());
+ }
+
+ int WriteDebug(gsl::span<const char> buffer) override {
+ if (debug_tty_ == nullptr) {
+ return buffer.size();
+ }
+ return debug_tty_->Write(buffer.data(), buffer.size());
+ }
+
+ private:
+ teensy::AcmTty *const stdout_tty_;
+ teensy::AcmTty *const debug_tty_;
+};
+
+// A printing implementation which creates its own UsbDevice and functions, and
+// manages their lifecycle.
+class DedicatedUsbPrinting final : public PrintingImplementation {
+ public:
+ DedicatedUsbPrinting();
+ ~DedicatedUsbPrinting() override;
+
+ void Initialize() override;
+
+ int WriteStdout(gsl::span<const char> buffer) override {
+ return stdout_tty_.Write(buffer.data(), buffer.size());
+ }
+
+ int WriteDebug(gsl::span<const char> buffer) override {
+ return debug_tty_.Write(buffer.data(), buffer.size());
+ }
+
+ private:
+ teensy::UsbDevice usb_device_;
+ teensy::AcmTty stdout_tty_;
+ teensy::AcmTty debug_tty_;
+};
+
+} // namespace motors
+} // namespace frc971
+
+#endif // MOTORS_PRINT_USB_H_