blob: f1257899e0948c7280e8b63da672b08bd493d47b [file] [log] [blame]
Brian Silverman4787a6e2018-10-06 16:00:54 -07001#include "motors/print/uart.h"
2
Brian Silverman4787a6e2018-10-06 16:00:54 -07003#include <atomic>
4
Philipp Schrader790cb542023-07-05 21:06:52 -07005#include "motors/core/kinetis.h"
6
Stephan Pleinesf63bde82024-01-13 15:59:33 -08007namespace frc971::motors {
Brian Silverman4787a6e2018-10-06 16:00:54 -07008namespace {
9
10::std::atomic<teensy::InterruptBufferedUart *> global_stdout{nullptr};
11
12} // namespace
13
14::std::unique_ptr<PrintingImplementation> CreatePrinting(
15 const PrintingParameters &parameters) {
16 if (parameters.stdout_uart_module == nullptr) {
17 return ::std::unique_ptr<PrintingImplementation>(new NopPrinting());
18 }
19 if (parameters.stdout_uart_module_clock_frequency == 0) {
20 return ::std::unique_ptr<PrintingImplementation>(new NopPrinting());
21 }
22 if (parameters.stdout_uart_status_interrupt < 0) {
23 return ::std::unique_ptr<PrintingImplementation>(new NopPrinting());
24 }
25 return ::std::unique_ptr<PrintingImplementation>(
26 new UartPrinting(parameters));
27}
28
29extern "C" void uart0_status_isr(void) {
30 teensy::InterruptBufferedUart *const tty =
31 global_stdout.load(::std::memory_order_relaxed);
32 DisableInterrupts disable_interrupts;
33 tty->HandleInterrupt(disable_interrupts);
34}
35
36UartPrinting::UartPrinting(const PrintingParameters &parameters)
37 : stdout_uart_{parameters.stdout_uart_module,
38 parameters.stdout_uart_module_clock_frequency},
39 stdout_status_interrupt_(parameters.stdout_uart_status_interrupt) {
40 stdout_uart_.Initialize(parameters.stdout_uart_baud_rate);
41}
42
43UartPrinting::~UartPrinting() {
44 NVIC_DISABLE_IRQ(stdout_status_interrupt_);
45 global_stdout.store(nullptr, ::std::memory_order_release);
46}
47
48void UartPrinting::Initialize() {
49 global_stdout.store(&stdout_uart_, ::std::memory_order_release);
50 NVIC_ENABLE_IRQ(stdout_status_interrupt_);
51}
52
Austin Schuh7fe04492022-01-02 13:37:21 -080053int UartPrinting::WriteStdout(absl::Span<const char> buffer) {
Brian Silverman4787a6e2018-10-06 16:00:54 -070054 stdout_uart_.Write(buffer);
55 return buffer.size();
56}
57
58extern "C" int _write(const int /*file*/, char *const ptr, const int len) {
59 teensy::InterruptBufferedUart *const tty =
60 global_stdout.load(::std::memory_order_acquire);
61 if (tty != nullptr) {
Austin Schuh7fe04492022-01-02 13:37:21 -080062 tty->Write(absl::MakeSpan(ptr, len));
Brian Silverman4787a6e2018-10-06 16:00:54 -070063 }
64 return len;
65}
66
Stephan Pleinesf63bde82024-01-13 15:59:33 -080067} // namespace frc971::motors