ssize_t UARTSerial::read(void* buffer, size_t length) { size_t data_read = 0; char *ptr = static_cast<char *>(buffer); api_lock(); while (_rxbuf.empty()) { if (!_blocking) { api_unlock(); return -EAGAIN; } api_unlock(); wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? api_lock(); } while (data_read < length && !_rxbuf.empty()) { _rxbuf.pop(*ptr++); data_read++; } api_unlock(); return data_read; }
int UARTSerial::sync() { api_lock(); while (!_txbuf.empty()) { api_unlock(); // Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it? wait_ms(1); api_lock(); } api_unlock(); return 0; }
ssize_t UARTSerial::read(void* buffer, size_t length) { size_t data_read = 0; char *ptr = static_cast<char *>(buffer); api_lock(); while (_rxbuf.empty()) { if (!_blocking) { api_unlock(); return -EAGAIN; } api_unlock(); wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? api_lock(); } while (data_read < length && !_rxbuf.empty()) { _rxbuf.pop(*ptr++); 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; }
ssize_t UARTSerial::write(const void* buffer, size_t length) { 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(); } 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(); api_unlock(); return data_written; }
void UARTSerial::set_flow_control(Flow type, PinName flow1, PinName flow2) { api_lock(); SerialBase::set_flow_control(type, flow1, flow2); api_unlock(); }
void UARTSerial::set_format(int bits, Parity parity, int stop_bits) { api_lock(); SerialBase::format(bits, parity, stop_bits); api_unlock(); }