mbed-dev-f303

Committer:
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4
Date:
Tue Jun 14 09:21:18 2022 +0000
Revision:
0:bdf663c61a82
lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 1 /* mbed Microcontroller Library
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 2 * Copyright (c) 2006-2017 ARM Limited
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 3 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 4 * Licensed under the Apache License, Version 2.0 (the "License");
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 5 * you may not use this file except in compliance with the License.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 6 * You may obtain a copy of the License at
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 7 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 8 * http://www.apache.org/licenses/LICENSE-2.0
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 9 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 10 * Unless required by applicable law or agreed to in writing, software
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 11 * distributed under the License is distributed on an "AS IS" BASIS,
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 13 * See the License for the specific language governing permissions and
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 14 * limitations under the License.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 15 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 16
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 17 #if (DEVICE_SERIAL && DEVICE_INTERRUPTIN)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 18
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 19 #include <errno.h>
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 20 #include "UARTSerial.h"
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 21 #include "platform/mbed_poll.h"
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 22 #include "platform/mbed_wait_api.h"
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 23
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 24 namespace mbed {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 25
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 26 UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 27 SerialBase(tx, rx, baud),
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 28 _blocking(true),
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 29 _tx_irq_enabled(false),
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 30 _dcd_irq(NULL)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 31 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 32 /* Attatch IRQ routines to the serial device. */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 33 SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 34 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 35
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 36 UARTSerial::~UARTSerial()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 37 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 38 delete _dcd_irq;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 39 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 40
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 41 void UARTSerial::dcd_irq()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 42 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 43 wake();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 44 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 45
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 46 void UARTSerial::set_baud(int baud)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 47 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 48 SerialBase::baud(baud);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 49 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 50
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 51 void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 52 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 53 delete _dcd_irq;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 54 _dcd_irq = NULL;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 55
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 56 if (dcd_pin != NC) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 57 _dcd_irq = new InterruptIn(dcd_pin);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 58 if (active_high) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 59 _dcd_irq->fall(callback(this, &UARTSerial::dcd_irq));
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 60 } else {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 61 _dcd_irq->rise(callback(this, &UARTSerial::dcd_irq));
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 62 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 63 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 64 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 65
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 66 int UARTSerial::close()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 67 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 68 /* Does not let us pass a file descriptor. So how to close ?
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 69 * Also, does it make sense to close a device type file descriptor*/
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 70 return 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 71 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 72
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 73 int UARTSerial::isatty()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 74 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 75 return 1;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 76
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 77 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 78
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 79 off_t UARTSerial::seek(off_t offset, int whence)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 80 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 81 /*XXX lseek can be done theoratically, but is it sane to mark positions on a dynamically growing/shrinking
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 82 * buffer system (from an interrupt context) */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 83 return -ESPIPE;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 84 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 85
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 86 int UARTSerial::sync()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 87 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 88 api_lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 89
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 90 while (!_txbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 91 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 92 // Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 93 wait_ms(1);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 94 api_lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 95 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 96
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 97 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 98
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 99 return 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 100 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 101
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 102 void UARTSerial::sigio(Callback<void()> func) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 103 core_util_critical_section_enter();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 104 _sigio_cb = func;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 105 if (_sigio_cb) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 106 short current_events = poll(0x7FFF);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 107 if (current_events) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 108 _sigio_cb();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 109 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 110 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 111 core_util_critical_section_exit();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 112 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 113
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 114 ssize_t UARTSerial::write(const void* buffer, size_t length)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 115 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 116 size_t data_written = 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 117 const char *buf_ptr = static_cast<const char *>(buffer);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 118
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 119 api_lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 120
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 121 while (_txbuf.full()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 122 if (!_blocking) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 123 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 124 return -EAGAIN;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 125 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 126 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 127 wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 128 api_lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 129 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 130
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 131 while (data_written < length && !_txbuf.full()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 132 _txbuf.push(*buf_ptr++);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 133 data_written++;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 134 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 135
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 136 core_util_critical_section_enter();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 137 if (!_tx_irq_enabled) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 138 UARTSerial::tx_irq(); // only write to hardware in one place
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 139 if (!_txbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 140 SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 141 _tx_irq_enabled = true;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 142 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 143 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 144 core_util_critical_section_exit();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 145
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 146 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 147
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 148 return data_written;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 149 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 150
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 151 ssize_t UARTSerial::read(void* buffer, size_t length)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 152 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 153 size_t data_read = 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 154
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 155 char *ptr = static_cast<char *>(buffer);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 156
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 157 api_lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 158
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 159 while (_rxbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 160 if (!_blocking) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 161 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 162 return -EAGAIN;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 163 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 164 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 165 wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 166 api_lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 167 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 168
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 169 while (data_read < length && !_rxbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 170 _rxbuf.pop(*ptr++);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 171 data_read++;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 172 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 173
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 174 api_unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 175
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 176 return data_read;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 177 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 178
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 179 bool UARTSerial::hup() const
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 180 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 181 return _dcd_irq && _dcd_irq->read() != 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 182 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 183
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 184 void UARTSerial::wake()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 185 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 186 if (_sigio_cb) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 187 _sigio_cb();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 188 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 189 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 190
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 191 short UARTSerial::poll(short events) const {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 192
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 193 short revents = 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 194 /* Check the Circular Buffer if space available for writing out */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 195
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 196
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 197 if (!_rxbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 198 revents |= POLLIN;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 199 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 200
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 201 /* POLLHUP and POLLOUT are mutually exclusive */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 202 if (hup()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 203 revents |= POLLHUP;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 204 } else if (!_txbuf.full()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 205 revents |= POLLOUT;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 206 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 207
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 208 /*TODO Handle other event types */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 209
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 210 return revents;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 211 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 212
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 213 void UARTSerial::lock()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 214 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 215 // This is the override for SerialBase.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 216 // No lock required as we only use SerialBase from interrupt or from
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 217 // inside our own critical section.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 218 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 219
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 220 void UARTSerial::unlock()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 221 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 222 // This is the override for SerialBase.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 223 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 224
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 225 void UARTSerial::api_lock(void)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 226 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 227 _mutex.lock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 228 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 229
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 230 void UARTSerial::api_unlock(void)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 231 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 232 _mutex.unlock();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 233 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 234
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 235 void UARTSerial::rx_irq(void)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 236 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 237 bool was_empty = _rxbuf.empty();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 238
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 239 /* Fill in the receive buffer if the peripheral is readable
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 240 * and receive buffer is not full. */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 241 while (SerialBase::readable()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 242 char data = SerialBase::_base_getc();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 243 if (!_rxbuf.full()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 244 _rxbuf.push(data);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 245 } else {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 246 /* Drop - can we report in some way? */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 247 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 248 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 249
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 250 /* Report the File handler that data is ready to be read from the buffer. */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 251 if (was_empty && !_rxbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 252 wake();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 253 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 254 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 255
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 256 // Also called from write to start transfer
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 257 void UARTSerial::tx_irq(void)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 258 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 259 bool was_full = _txbuf.full();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 260
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 261 /* Write to the peripheral if there is something to write
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 262 * and if the peripheral is available to write. */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 263 while (!_txbuf.empty() && SerialBase::writeable()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 264 char data;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 265 _txbuf.pop(data);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 266 SerialBase::_base_putc(data);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 267 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 268
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 269 if (_tx_irq_enabled && _txbuf.empty()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 270 SerialBase::attach(NULL, TxIrq);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 271 _tx_irq_enabled = false;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 272 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 273
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 274 /* Report the File handler that data can be written to peripheral. */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 275 if (was_full && !_txbuf.full() && !hup()) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 276 wake();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 277 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 278 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 279
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 280 } //namespace mbed
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 281
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 282 #endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 283