blob: ca40ab720272f34091356cbbeb691bdcf65f1d7d [file] [log] [blame]
Brian Silverman55c62022018-09-03 19:13:44 -07001#ifndef MOTORS_PERIPHERAL_UART_H_
2#define MOTORS_PERIPHERAL_UART_H_
3
4#include "motors/core/kinetis.h"
5#include "motors/peripheral/uart_buffer.h"
6#include "motors/util.h"
7#include "third_party/GSL/include/gsl/gsl"
8
9namespace frc971 {
10namespace teensy {
11
12// Simple synchronous interface to a UART.
13class Uart {
14 public:
15 Uart(KINETISK_UART_t *module, int module_clock_frequency)
16 : module_(module), module_clock_frequency_(module_clock_frequency) {}
17 Uart(const Uart &) = delete;
18 ~Uart();
19 Uart &operator=(const Uart &) = delete;
20
21 void Initialize(int baud_rate);
22
23 // Blocks until all of the data is at least queued.
Brian Silverman4787a6e2018-10-06 16:00:54 -070024 void Write(gsl::span<const char> data, const DisableInterrupts &) {
25 DoWrite(data);
26 }
Brian Silverman55c62022018-09-03 19:13:44 -070027
28 bool SpaceAvailable() const { return module_->S1 & M_UART_TDRE; }
29 // Only call this if SpaceAvailable() has just returned true.
30 void WriteCharacter(char c) { module_->D = c; }
31
32 void EnableTransmitInterrupt() {
33 c2_value_ |= M_UART_TIE;
34 module_->C2 = c2_value_;
35 }
36
37 void DisableTransmitInterrupt() {
38 c2_value_ &= ~M_UART_TIE;
39 module_->C2 = c2_value_;
40 }
41
42 private:
Brian Silverman4787a6e2018-10-06 16:00:54 -070043 void DoWrite(gsl::span<const char> data);
Brian Silverman55c62022018-09-03 19:13:44 -070044
45 KINETISK_UART_t *const module_;
46 const int module_clock_frequency_;
47 // What we put in C2 except TE.
48 uint8_t c2_value_;
49
50 int tx_fifo_size_, rx_fifo_size_;
51};
52
53// Interrupt-based buffered interface to a UART.
54class InterruptBufferedUart {
55 public:
56 InterruptBufferedUart(KINETISK_UART_t *module, int module_clock_frequency)
57 : uart_(module, module_clock_frequency) {}
58
59 void Initialize(int baud_rate);
60
Brian Silverman4787a6e2018-10-06 16:00:54 -070061 void Write(gsl::span<const char> data);
Brian Silverman55c62022018-09-03 19:13:44 -070062
63 // Should be called as the body of the interrupt handler.
64 void HandleInterrupt(const DisableInterrupts &disable_interrupts) {
65 WriteCharacters(true, disable_interrupts);
66 }
67
68 private:
69 void WriteCharacters(bool disable_empty, const DisableInterrupts &);
70
71 Uart uart_;
72 UartBuffer<1024> buffer_;
73
74 bool interrupt_enabled_ = false;
75};
76
77} // namespace teensy
78} // namespace frc971
79
80#endif // MOTORS_PERIPHERAL_UART_H_