Merge pull request #5088 from kjbracey-arm/uartserial_flow

UARTSerial: add flow control and format APIs
pull/5338/merge
Jimmy Brisson 2017-11-02 10:37:40 -05:00 committed by GitHub
commit 5768693e0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 6 deletions

View File

@ -32,6 +32,7 @@ UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
SerialBase(tx, rx, baud),
_blocking(true),
_tx_irq_enabled(false),
_rx_irq_enabled(true),
_dcd_irq(NULL)
{
/* Attatch IRQ routines to the serial device. */
@ -68,6 +69,22 @@ void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
}
}
void UARTSerial::set_format(int bits, Parity parity, int stop_bits)
{
api_lock();
SerialBase::format(bits, parity, stop_bits);
api_unlock();
}
#if DEVICE_SERIAL_FC
void UARTSerial::set_flow_control(Flow type, PinName flow1, PinName flow2)
{
api_lock();
SerialBase::set_flow_control(type, flow1, flow2);
api_unlock();
}
#endif
int UARTSerial::close()
{
/* 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)
data_read++;
}
core_util_critical_section_enter();
if (!_rx_irq_enabled) {
UARTSerial::rx_irq(); // only read from hardware in one place
if (!_rxbuf.full()) {
SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
_rx_irq_enabled = true;
}
}
core_util_critical_section_exit();
api_unlock();
return data_read;
@ -243,13 +270,14 @@ void UARTSerial::rx_irq(void)
/* Fill in the receive buffer if the peripheral is readable
* and receive buffer is not full. */
while (SerialBase::readable()) {
while (!_rxbuf.full() && SerialBase::readable()) {
char data = SerialBase::_base_getc();
if (!_rxbuf.full()) {
_rxbuf.push(data);
} else {
/* Drop - can we report in some way? */
}
_rxbuf.push(data);
}
if (_rx_irq_enabled && _rxbuf.full()) {
SerialBase::attach(NULL, RxIrq);
_rx_irq_enabled = false;
}
/* Report the File handler that data is ready to be read from the buffer. */

View File

@ -164,6 +164,42 @@ public:
*/
void set_baud(int baud);
// Expose private SerialBase::Parity as UARTSerial::Parity
using SerialBase::Parity;
// In C++11, we wouldn't need to also have using directives for each value
using SerialBase::None;
using SerialBase::Odd;
using SerialBase::Even;
using SerialBase::Forced1;
using SerialBase::Forced0;
/** Set the transmission format used by the serial port
*
* @param bits The number of bits in a word (5-8; default = 8)
* @param parity The parity used (None, Odd, Even, Forced1, Forced0; default = None)
* @param stop_bits The number of stop bits (1 or 2; default = 1)
*/
void set_format(int bits=8, Parity parity=UARTSerial::None, int stop_bits=1);
#if DEVICE_SERIAL_FC
// For now use the base enum - but in future we may have extra options
// such as XON/XOFF or manual GPIO RTSCTS.
using SerialBase::Flow;
// In C++11, we wouldn't need to also have using directives for each value
using SerialBase::Disabled;
using SerialBase::RTS;
using SerialBase::CTS;
using SerialBase::RTSCTS;
/** Set the flow control type on the serial port
*
* @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
* @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
* @param flow2 the second flow control pin (CTS for RTSCTS)
*/
void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC);
#endif
private:
void wait_ms(uint32_t millisec);
@ -192,6 +228,7 @@ private:
bool _blocking;
bool _tx_irq_enabled;
bool _rx_irq_enabled;
InterruptIn *_dcd_irq;
/** Device Hanged up