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