blob: 7ec7cf26ece2c90a156bea7d1ae9ac1878572411 [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
Austin Schuh7fe04492022-01-02 13:37:21 -08006#include "absl/types/span.h"
Philipp Schrader790cb542023-07-05 21:06:52 -07007
Brian Silverman83693e42019-03-02 15:45:52 -08008#include "aos/containers/sized_array.h"
Brian Silverman4787a6e2018-10-06 16:00:54 -07009#include "motors/core/kinetis.h"
Brian Silverman4787a6e2018-10-06 16:00:54 -070010
11namespace frc971 {
12namespace teensy {
13
14class AcmTty;
15
16} // namespace teensy
17namespace motors {
18
19class PrintingImplementation {
20 public:
21 PrintingImplementation() = default;
22 virtual ~PrintingImplementation() = default;
23
24 PrintingImplementation(const PrintingImplementation &) = delete;
25 PrintingImplementation &operator=(const PrintingImplementation &) = delete;
26
27 virtual void Initialize() = 0;
28
29 // Writes something directly to stdout/stderr (they are treated as the same).
Austin Schuh7fe04492022-01-02 13:37:21 -080030 virtual int WriteStdout(absl::Span<const char> buffer) = 0;
Brian Silverman4787a6e2018-10-06 16:00:54 -070031 // Writes something to a separate debug stream. Some implementations will
32 // always ignore this, and others will ignore it under some conditions.
Austin Schuh7fe04492022-01-02 13:37:21 -080033 virtual int WriteDebug(absl::Span<const char> buffer) {
34 return buffer.size();
35 }
Brian Silverman83693e42019-03-02 15:45:52 -080036
37 // Reads any characters which are available (never blocks).
38 //
39 // The default never returns any data.
40 virtual aos::SizedArray<char, 4> ReadStdin() { return {}; }
Brian Silverman4787a6e2018-10-06 16:00:54 -070041};
42
43// A trivial printing "implementation" which simply does nothing. This is used
44// when a real implementation can't be created by CreatePrinting due to missing
45// parameters.
46class NopPrinting : public PrintingImplementation {
47 public:
48 NopPrinting() = default;
49 ~NopPrinting() override = default;
50
51 void Initialize() override {}
Austin Schuh7fe04492022-01-02 13:37:21 -080052 int WriteStdout(absl::Span<const char> buffer) override {
Brian Silverman4787a6e2018-10-06 16:00:54 -070053 return buffer.size();
54 }
55};
56
57// Contains various parameters for controlling how the printing implementation
58// is initialized. Some of these are optional depending on which implementation
59// is selected, while others being missing will result in some implementations
60// turning into NOPs.
61struct PrintingParameters {
62 // This module must have its clock enabled and pinmuxing set up before calling
63 // CreatePrinting.
64 KINETISK_UART_t *stdout_uart_module = nullptr;
65 int stdout_uart_module_clock_frequency = 0;
66 int stdout_uart_baud_rate = 115200;
67 int stdout_uart_status_interrupt = -1;
68
69 // Setting this to true indicates the implementation should manage its own
70 // UsbDevice. If there are other USB functions around, set stdout_tty (and
71 // optionally debug_tty) instead.
72 bool dedicated_usb = false;
73
74 // If these are used, Initialize() must be called on the UsbDevice before the
75 // PrintingImplementation.
76 teensy::AcmTty *stdout_tty = nullptr;
77 teensy::AcmTty *debug_tty = nullptr;
78};
79
80// Creates an implementation of the linked-in type. Exactly one printing
81// implementation must be linked in. If all the necessary parameters aren't
82// filled out, this will return a NopPrinting instance.
83//
84// Some implementations will work even before calling this, or calling
85// Initialize() on the result. Others do require calling this before they will
86// work. This must be called before enabling any interrupts or some
87// implementations may deadlock.
88//
89// This should only be called once per program lifetime. Many implementations
90// manage global resources in the returned object. The resulting object may be
91// destroyed, but not while interrupts might be running. Destroying the object
92// may or may not stop printing.
93//
94// This will not enable any interrupts. When applicable, that is deferred until
95// Initialize() is called on the result.
96::std::unique_ptr<PrintingImplementation> CreatePrinting(
97 const PrintingParameters &parameters);
98
99} // namespace motors
100} // namespace frc971
101
102#endif // MOTORS_PRINT_PRINT_H_