Opencv 3.1 project on GR-PEACH board

Fork of gr-peach-opencv-project by the do

Committer:
thedo
Date:
Tue Jul 04 06:23:13 2017 +0000
Revision:
170:54ff26da7eb6
Parent:
166:3a9487d57a5c
project opencv 3.1 on GR PEACH board, no use SD card.

Who changed what in which revision?

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