blob: d51a2c39872a77140eccd071b0d2652cda61f3f2 [file] [log] [blame]
Brian Silverman4787a6e2018-10-06 16:00:54 -07001#ifndef MOTORS_PRINT_PRINT_H_
2#define MOTORS_PRINT_PRINT_H_
3
4#include <memory>
5
6#include "motors/core/kinetis.h"
7#include "third_party/GSL/include/gsl/gsl"
8
9namespace frc971 {
10namespace teensy {
11
12class AcmTty;
13
14} // namespace teensy
15namespace motors {
16
17class PrintingImplementation {
18 public:
19 PrintingImplementation() = default;
20 virtual ~PrintingImplementation() = default;
21
22 PrintingImplementation(const PrintingImplementation &) = delete;
23 PrintingImplementation &operator=(const PrintingImplementation &) = delete;
24
25 virtual void Initialize() = 0;
26
27 // Writes something directly to stdout/stderr (they are treated as the same).
28 virtual int WriteStdout(gsl::span<const char> buffer) = 0;
29 // Writes something to a separate debug stream. Some implementations will
30 // always ignore this, and others will ignore it under some conditions.
31 virtual int WriteDebug(gsl::span<const char> buffer) { return buffer.size(); }
32};
33
34// A trivial printing "implementation" which simply does nothing. This is used
35// when a real implementation can't be created by CreatePrinting due to missing
36// parameters.
37class NopPrinting : public PrintingImplementation {
38 public:
39 NopPrinting() = default;
40 ~NopPrinting() override = default;
41
42 void Initialize() override {}
43 int WriteStdout(gsl::span<const char> buffer) override {
44 return buffer.size();
45 }
46};
47
48// Contains various parameters for controlling how the printing implementation
49// is initialized. Some of these are optional depending on which implementation
50// is selected, while others being missing will result in some implementations
51// turning into NOPs.
52struct PrintingParameters {
53 // This module must have its clock enabled and pinmuxing set up before calling
54 // CreatePrinting.
55 KINETISK_UART_t *stdout_uart_module = nullptr;
56 int stdout_uart_module_clock_frequency = 0;
57 int stdout_uart_baud_rate = 115200;
58 int stdout_uart_status_interrupt = -1;
59
60 // Setting this to true indicates the implementation should manage its own
61 // UsbDevice. If there are other USB functions around, set stdout_tty (and
62 // optionally debug_tty) instead.
63 bool dedicated_usb = false;
64
65 // If these are used, Initialize() must be called on the UsbDevice before the
66 // PrintingImplementation.
67 teensy::AcmTty *stdout_tty = nullptr;
68 teensy::AcmTty *debug_tty = nullptr;
69};
70
71// Creates an implementation of the linked-in type. Exactly one printing
72// implementation must be linked in. If all the necessary parameters aren't
73// filled out, this will return a NopPrinting instance.
74//
75// Some implementations will work even before calling this, or calling
76// Initialize() on the result. Others do require calling this before they will
77// work. This must be called before enabling any interrupts or some
78// implementations may deadlock.
79//
80// This should only be called once per program lifetime. Many implementations
81// manage global resources in the returned object. The resulting object may be
82// destroyed, but not while interrupts might be running. Destroying the object
83// may or may not stop printing.
84//
85// This will not enable any interrupts. When applicable, that is deferred until
86// Initialize() is called on the result.
87::std::unique_ptr<PrintingImplementation> CreatePrinting(
88 const PrintingParameters &parameters);
89
90} // namespace motors
91} // namespace frc971
92
93#endif // MOTORS_PRINT_PRINT_H_