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