Skip to content

Commit 5768693

Browse files
Merge pull request #5088 from kjbracey-arm/uartserial_flow
UARTSerial: add flow control and format APIs
2 parents 1454e6b + c262a03 commit 5768693

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

drivers/UARTSerial.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
3232
SerialBase(tx, rx, baud),
3333
_blocking(true),
3434
_tx_irq_enabled(false),
35+
_rx_irq_enabled(true),
3536
_dcd_irq(NULL)
3637
{
3738
/* Attatch IRQ routines to the serial device. */
@@ -68,6 +69,22 @@ void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
6869
}
6970
}
7071

72+
void UARTSerial::set_format(int bits, Parity parity, int stop_bits)
73+
{
74+
api_lock();
75+
SerialBase::format(bits, parity, stop_bits);
76+
api_unlock();
77+
}
78+
79+
#if DEVICE_SERIAL_FC
80+
void UARTSerial::set_flow_control(Flow type, PinName flow1, PinName flow2)
81+
{
82+
api_lock();
83+
SerialBase::set_flow_control(type, flow1, flow2);
84+
api_unlock();
85+
}
86+
#endif
87+
7188
int UARTSerial::close()
7289
{
7390
/* Does not let us pass a file descriptor. So how to close ?
@@ -176,6 +193,16 @@ ssize_t UARTSerial::read(void* buffer, size_t length)
176193
data_read++;
177194
}
178195

196+
core_util_critical_section_enter();
197+
if (!_rx_irq_enabled) {
198+
UARTSerial::rx_irq(); // only read from hardware in one place
199+
if (!_rxbuf.full()) {
200+
SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
201+
_rx_irq_enabled = true;
202+
}
203+
}
204+
core_util_critical_section_exit();
205+
179206
api_unlock();
180207

181208
return data_read;
@@ -243,13 +270,14 @@ void UARTSerial::rx_irq(void)
243270

244271
/* Fill in the receive buffer if the peripheral is readable
245272
* and receive buffer is not full. */
246-
while (SerialBase::readable()) {
273+
while (!_rxbuf.full() && SerialBase::readable()) {
247274
char data = SerialBase::_base_getc();
248-
if (!_rxbuf.full()) {
249-
_rxbuf.push(data);
250-
} else {
251-
/* Drop - can we report in some way? */
252-
}
275+
_rxbuf.push(data);
276+
}
277+
278+
if (_rx_irq_enabled && _rxbuf.full()) {
279+
SerialBase::attach(NULL, RxIrq);
280+
_rx_irq_enabled = false;
253281
}
254282

255283
/* Report the File handler that data is ready to be read from the buffer. */

drivers/UARTSerial.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,42 @@ class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UA
164164
*/
165165
void set_baud(int baud);
166166

167+
// Expose private SerialBase::Parity as UARTSerial::Parity
168+
using SerialBase::Parity;
169+
// In C++11, we wouldn't need to also have using directives for each value
170+
using SerialBase::None;
171+
using SerialBase::Odd;
172+
using SerialBase::Even;
173+
using SerialBase::Forced1;
174+
using SerialBase::Forced0;
175+
176+
/** Set the transmission format used by the serial port
177+
*
178+
* @param bits The number of bits in a word (5-8; default = 8)
179+
* @param parity The parity used (None, Odd, Even, Forced1, Forced0; default = None)
180+
* @param stop_bits The number of stop bits (1 or 2; default = 1)
181+
*/
182+
void set_format(int bits=8, Parity parity=UARTSerial::None, int stop_bits=1);
183+
184+
#if DEVICE_SERIAL_FC
185+
// For now use the base enum - but in future we may have extra options
186+
// such as XON/XOFF or manual GPIO RTSCTS.
187+
using SerialBase::Flow;
188+
// In C++11, we wouldn't need to also have using directives for each value
189+
using SerialBase::Disabled;
190+
using SerialBase::RTS;
191+
using SerialBase::CTS;
192+
using SerialBase::RTSCTS;
193+
194+
/** Set the flow control type on the serial port
195+
*
196+
* @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
197+
* @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
198+
* @param flow2 the second flow control pin (CTS for RTSCTS)
199+
*/
200+
void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC);
201+
#endif
202+
167203
private:
168204

169205
void wait_ms(uint32_t millisec);
@@ -192,6 +228,7 @@ class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UA
192228

193229
bool _blocking;
194230
bool _tx_irq_enabled;
231+
bool _rx_irq_enabled;
195232
InterruptIn *_dcd_irq;
196233

197234
/** Device Hanged up

0 commit comments

Comments
 (0)