Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Pic32mxUart.hxx
Go to the documentation of this file.
1
36#ifndef _FREERTOS_DRIVERS_PIC32MX_PIC32MXUART_HXX_
37#define _FREERTOS_DRIVERS_PIC32MX_PIC32MXUART_HXX_
38
39#include "Serial.hxx"
40#include "peripheral/uart.h"
41
42extern "C"
43{
44 extern const unsigned long pic32_periph_clock_hz;
45}
46
47class Pic32mxUart : public Serial
48{
49public:
50 Pic32mxUart(const char *name, UART_MODULE periph, uint32_t int_vec,
51 unsigned baud = 115200, bool enable_rts_cts = false)
52 : Serial(name)
53 , hw_(periph)
54 , intVector_(int_vec)
55 {
56 unsigned rtscfg = UART_ENABLE_PINS_TX_RX_ONLY;
57 if (enable_rts_cts)
58 {
59 rtscfg = UART_ENABLE_PINS_CTS_RTS | UART_RTS_WHEN_RX_NOT_FULL;
60 }
61 UARTConfigure(
62 hw_, (UART_CONFIGURATION)(UART_ENABLE_HIGH_SPEED | rtscfg));
63 UARTSetFifoMode(hw_,
64 (UART_FIFO_MODE)(UART_INTERRUPT_ON_TX_NOT_FULL |
65 UART_INTERRUPT_ON_RX_NOT_EMPTY));
66 UARTSetLineControl(hw_,
67 (UART_LINE_CONTROL_MODE)(
68 UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1));
69 UARTSetDataRate(hw_, get_pclk(), baud);
70
71 INTSetVectorPriority(int_vector(), INT_PRIORITY_LEVEL_3);
72 INTSetVectorSubPriority(int_vector(), INT_SUB_PRIORITY_LEVEL_0);
73 }
74
75 void enable() override
76 {
77 UARTEnable(hw_,
78 (UART_ENABLE_MODE)(
79 UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)));
80
81 // Configure UART2 RX Interrupt
82 INTEnable(rx_int(), INT_ENABLED);
83 }
84
85 void disable() override
86 {
87 // We do not disable TX as we might still have some unsent data in our
88 // buffer.
89 UARTEnable(hw_, (UART_ENABLE_MODE)(UART_DISABLE_FLAGS(UART_RX)));
90 INTEnable(rx_int(), INT_DISABLED);
91 }
92
93 inline void interrupt_handler()
94 {
95 if (INTGetFlag(rx_int()))
96 {
97 numIrqRx_++;
99 {
101 }
102 INTClearFlag(rx_int());
103 }
104 if (INTGetFlag(tx_int()) && INTGetEnable(tx_int()))
105 {
106 numIrqTx_++;
107 if (send_some_data())
108 {
110 }
111 INTClearFlag(tx_int());
112 }
113 numIrq_++;
114 }
115
116 void tx_char() override
117 {
118 if (send_some_data())
119 {
121 }
122 }
123
124private:
130 {
131 bool has = false;
132 while (UARTReceivedDataIsAvailable(hw_))
133 {
134 auto d = UARTGetDataByte(hw_);
135 if (rxBuf->put(&d, 1) == 0)
136 {
137 ++overrunCount;
138 }
139 has = true;
140 }
141 return has;
142 }
143
149 {
150 bool has = false;
151 while (true)
152 {
153 if (!txBuf->pending())
154 {
155 // Nothing to send. Do not wait for interrupts.
156 INTEnable(tx_int(), INT_DISABLED);
157 return has;
158 }
159 if (!UARTTransmitterIsReady(hw_))
160 {
161 // FIFO full. Wait with interrupt.
162 INTEnable(tx_int(), INT_ENABLED);
163 return has;
164 }
165 uint8_t d;
166 txBuf->get(&d, 1);
167 UARTSendDataByte(hw_, d);
168 has = true;
169 }
170 }
171
172 inline unsigned get_pclk()
173 {
174 return pic32_periph_clock_hz;
175 }
176
177 inline INT_SOURCE tx_int()
178 {
179 return (INT_SOURCE)INT_SOURCE_UART_TX(hw_);
180 }
181
182 inline INT_SOURCE rx_int()
183 {
184 return (INT_SOURCE)INT_SOURCE_UART_RX(hw_);
185 }
186
187 inline INT_VECTOR int_vector()
188 {
189 return (INT_VECTOR)(INT_VECTOR_UART(hw_));
190 }
191
194 UART_MODULE hw_;
197 unsigned intVector_;
199 unsigned numIrq_ = 0;
201 unsigned numIrqTx_ = 0;
203 unsigned numIrqRx_ = 0;
204};
205
206#endif // _FREERTOS_DRIVERS_PIC32MX_PIC32MXUART_HXX_
void signal_condition()
Signal the wakeup condition.
size_t pending()
Return the number of items in the queue.
void signal_condition_from_isr()
Signal the wakeup condition from an ISR context.
size_t get(T *buf, size_t items)
remove a number of items from the buffer.
size_t put(const T *buf, size_t items)
Insert a number of items to the buffer.
const char * name
device name
Definition Devtab.hxx:266
void disable() override
This will be called when reference count goes from non-zero to 0.
bool send_some_data()
Copies data from the tx buffer to the hardware send register / fifo.
unsigned numIrq_
Stats variable.
unsigned numIrqTx_
Stats variable.
unsigned intVector_
This is the hardware vector number for the UART module.
bool receive_some_data()
Copies data from the RX fifo into the receive ring buffer.
void enable() override
This will be called once when reference-count goes from 0 to positive.
unsigned numIrqRx_
Stats variable.
void tx_char() override
Function to try and transmit a character.
UART_MODULE hw_
Enum describing which uart module we are using.
Private data for a serial device.
Definition Serial.hxx:46
DeviceBuffer< uint8_t > * rxBuf
receive buffer
Definition Serial.hxx:85
DeviceBuffer< uint8_t > * txBuf
transmit buffer
Definition Serial.hxx:84
unsigned int overrunCount
overrun count
Definition Serial.hxx:86