blob: cf79815ba83f6665391595ea820d097d8ff31f8a [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.
24 void Write(gsl::span<char> data, const DisableInterrupts &) { DoWrite(data); }
25
26 bool SpaceAvailable() const { return module_->S1 & M_UART_TDRE; }
27 // Only call this if SpaceAvailable() has just returned true.
28 void WriteCharacter(char c) { module_->D = c; }
29
30 void EnableTransmitInterrupt() {
31 c2_value_ |= M_UART_TIE;
32 module_->C2 = c2_value_;
33 }
34
35 void DisableTransmitInterrupt() {
36 c2_value_ &= ~M_UART_TIE;
37 module_->C2 = c2_value_;
38 }
39
40 private:
41 void DoWrite(gsl::span<char> data);
42
43 KINETISK_UART_t *const module_;
44 const int module_clock_frequency_;
45 // What we put in C2 except TE.
46 uint8_t c2_value_;
47
48 int tx_fifo_size_, rx_fifo_size_;
49};
50
51// Interrupt-based buffered interface to a UART.
52class InterruptBufferedUart {
53 public:
54 InterruptBufferedUart(KINETISK_UART_t *module, int module_clock_frequency)
55 : uart_(module, module_clock_frequency) {}
56
57 void Initialize(int baud_rate);
58
59 void Write(gsl::span<char> data, const DisableInterrupts &disable_interrupts);
60
61 // Should be called as the body of the interrupt handler.
62 void HandleInterrupt(const DisableInterrupts &disable_interrupts) {
63 WriteCharacters(true, disable_interrupts);
64 }
65
66 private:
67 void WriteCharacters(bool disable_empty, const DisableInterrupts &);
68
69 Uart uart_;
70 UartBuffer<1024> buffer_;
71
72 bool interrupt_enabled_ = false;
73};
74
75} // namespace teensy
76} // namespace frc971
77
78#endif // MOTORS_PERIPHERAL_UART_H_