mbed library sources, mbed-dev only for TYBLE16
Fork of mbed-dev by
Please refer flowing link.
/users/kenjiArai/notebook/tyble16-module-will-become-a-mbed-family--mbedliza/
Diff: drivers/UARTSerial.cpp
- Revision:
- 180:96ed750bd169
- Parent:
- 176:447f873cad2f
diff -r b0033dcd6934 -r 96ed750bd169 drivers/UARTSerial.cpp --- a/drivers/UARTSerial.cpp Thu Dec 07 14:01:42 2017 +0000 +++ b/drivers/UARTSerial.cpp Wed Jan 17 15:23:54 2018 +0000 @@ -32,6 +32,7 @@ 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_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 ? @@ -121,36 +138,47 @@ size_t data_written = 0; const char *buf_ptr = static_cast<const char *>(buffer); - api_lock(); - - while (_txbuf.full()) { - if (!_blocking) { - api_unlock(); - return -EAGAIN; - } - api_unlock(); - wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? - api_lock(); + if (length == 0) { + return 0; } - while (data_written < length && !_txbuf.full()) { - _txbuf.push(*buf_ptr++); - data_written++; - } + api_lock(); + + // Unlike read, we should write the whole thing if blocking. POSIX only + // allows partial as a side-effect of signal handling; it normally tries to + // write everything if blocking. Without signals we can always write all. + while (data_written < length) { - core_util_critical_section_enter(); - if (!_tx_irq_enabled) { - UARTSerial::tx_irq(); // only write to hardware in one place - if (!_txbuf.empty()) { - SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq); - _tx_irq_enabled = true; + if (_txbuf.full()) { + if (!_blocking) { + break; + } + do { + api_unlock(); + wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? + api_lock(); + } while (_txbuf.full()); } + + while (data_written < length && !_txbuf.full()) { + _txbuf.push(*buf_ptr++); + data_written++; + } + + core_util_critical_section_enter(); + if (!_tx_irq_enabled) { + UARTSerial::tx_irq(); // only write to hardware in one place + if (!_txbuf.empty()) { + SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq); + _tx_irq_enabled = true; + } + } + core_util_critical_section_exit(); } - core_util_critical_section_exit(); api_unlock(); - return data_written; + return data_written != 0 ? (ssize_t) data_written : (ssize_t) -EAGAIN; } ssize_t UARTSerial::read(void* buffer, size_t length) @@ -159,6 +187,10 @@ char *ptr = static_cast<char *>(buffer); + if (length == 0) { + return 0; + } + api_lock(); while (_rxbuf.empty()) { @@ -176,6 +208,16 @@ 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 +285,14 @@ /* 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. */