Forked from LibPN532

Dependents:   NFC_Secure_Access NFC_Secure_Access

Fork of LibPN532 by dotnfc Tang

Committer:
udareaniket
Date:
Sun Apr 22 23:29:20 2018 +0000
Revision:
2:9a2ab3fa7862
Parent:
0:db8030e71f55
Initial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dotnfc 0:db8030e71f55 1 /**
dotnfc 0:db8030e71f55 2 * @file BufferedSerial.cpp
dotnfc 0:db8030e71f55 3 * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
dotnfc 0:db8030e71f55 4 * @author sam grove
dotnfc 0:db8030e71f55 5 * @version 1.0
dotnfc 0:db8030e71f55 6 * @see
dotnfc 0:db8030e71f55 7 *
dotnfc 0:db8030e71f55 8 * Copyright (c) 2013
dotnfc 0:db8030e71f55 9 *
dotnfc 0:db8030e71f55 10 * Licensed under the Apache License, Version 2.0 (the "License");
dotnfc 0:db8030e71f55 11 * you may not use this file except in compliance with the License.
dotnfc 0:db8030e71f55 12 * You may obtain a copy of the License at
dotnfc 0:db8030e71f55 13 *
dotnfc 0:db8030e71f55 14 * http://www.apache.org/licenses/LICENSE-2.0
dotnfc 0:db8030e71f55 15 *
dotnfc 0:db8030e71f55 16 * Unless required by applicable law or agreed to in writing, software
dotnfc 0:db8030e71f55 17 * distributed under the License is distributed on an "AS IS" BASIS,
dotnfc 0:db8030e71f55 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dotnfc 0:db8030e71f55 19 * See the License for the specific language governing permissions and
dotnfc 0:db8030e71f55 20 * limitations under the License.
dotnfc 0:db8030e71f55 21 */
dotnfc 0:db8030e71f55 22
dotnfc 0:db8030e71f55 23 #include "BufferedSerial.h"
dotnfc 0:db8030e71f55 24 #include <stdarg.h>
dotnfc 0:db8030e71f55 25
dotnfc 0:db8030e71f55 26 BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
dotnfc 0:db8030e71f55 27 : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
dotnfc 0:db8030e71f55 28 {
dotnfc 0:db8030e71f55 29 RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
dotnfc 0:db8030e71f55 30 this->_buf_size = buf_size;
dotnfc 0:db8030e71f55 31 this->_tx_multiple = tx_multiple;
dotnfc 0:db8030e71f55 32 return;
dotnfc 0:db8030e71f55 33 }
dotnfc 0:db8030e71f55 34
dotnfc 0:db8030e71f55 35 BufferedSerial::~BufferedSerial(void)
dotnfc 0:db8030e71f55 36 {
dotnfc 0:db8030e71f55 37 RawSerial::attach(NULL, RawSerial::RxIrq);
dotnfc 0:db8030e71f55 38 RawSerial::attach(NULL, RawSerial::TxIrq);
dotnfc 0:db8030e71f55 39
dotnfc 0:db8030e71f55 40 return;
dotnfc 0:db8030e71f55 41 }
dotnfc 0:db8030e71f55 42
dotnfc 0:db8030e71f55 43 int BufferedSerial::readable(void)
dotnfc 0:db8030e71f55 44 {
dotnfc 0:db8030e71f55 45 return _rxbuf.available(); // note: look if things are in the buffer
dotnfc 0:db8030e71f55 46 }
dotnfc 0:db8030e71f55 47
dotnfc 0:db8030e71f55 48 int BufferedSerial::writeable(void)
dotnfc 0:db8030e71f55 49 {
dotnfc 0:db8030e71f55 50 return 1; // buffer allows overwriting by design, always true
dotnfc 0:db8030e71f55 51 }
dotnfc 0:db8030e71f55 52
dotnfc 0:db8030e71f55 53 int BufferedSerial::getc(void)
dotnfc 0:db8030e71f55 54 {
dotnfc 0:db8030e71f55 55 if (_rxbuf.available())
dotnfc 0:db8030e71f55 56 return _rxbuf;
dotnfc 0:db8030e71f55 57 else
dotnfc 0:db8030e71f55 58 return -1; // no more data
dotnfc 0:db8030e71f55 59 }
dotnfc 0:db8030e71f55 60
dotnfc 0:db8030e71f55 61 int BufferedSerial::putc(int c)
dotnfc 0:db8030e71f55 62 {
dotnfc 0:db8030e71f55 63 _txbuf = (char)c;
dotnfc 0:db8030e71f55 64 BufferedSerial::prime();
dotnfc 0:db8030e71f55 65
dotnfc 0:db8030e71f55 66 return c;
dotnfc 0:db8030e71f55 67 }
dotnfc 0:db8030e71f55 68
dotnfc 0:db8030e71f55 69 int BufferedSerial::puts(const char *s)
dotnfc 0:db8030e71f55 70 {
dotnfc 0:db8030e71f55 71 if (s != NULL) {
dotnfc 0:db8030e71f55 72 const char* ptr = s;
dotnfc 0:db8030e71f55 73
dotnfc 0:db8030e71f55 74 while(*(ptr) != 0) {
dotnfc 0:db8030e71f55 75 _txbuf = *(ptr++);
dotnfc 0:db8030e71f55 76 }
dotnfc 0:db8030e71f55 77 _txbuf = '\n'; // done per puts definition
dotnfc 0:db8030e71f55 78 BufferedSerial::prime();
dotnfc 0:db8030e71f55 79
dotnfc 0:db8030e71f55 80 return (ptr - s) + 1;
dotnfc 0:db8030e71f55 81 }
dotnfc 0:db8030e71f55 82 return 0;
dotnfc 0:db8030e71f55 83 }
dotnfc 0:db8030e71f55 84
dotnfc 0:db8030e71f55 85 int BufferedSerial::printf(const char* format, ...)
dotnfc 0:db8030e71f55 86 {
dotnfc 0:db8030e71f55 87 char buffer[this->_buf_size];
dotnfc 0:db8030e71f55 88 memset(buffer,0,this->_buf_size);
dotnfc 0:db8030e71f55 89 int r = 0;
dotnfc 0:db8030e71f55 90
dotnfc 0:db8030e71f55 91 va_list arg;
dotnfc 0:db8030e71f55 92 va_start(arg, format);
dotnfc 0:db8030e71f55 93 r = vsprintf(buffer, format, arg);
dotnfc 0:db8030e71f55 94 // this may not hit the heap but should alert the user anyways
dotnfc 0:db8030e71f55 95 if(r > this->_buf_size) {
dotnfc 0:db8030e71f55 96 error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
dotnfc 0:db8030e71f55 97 va_end(arg);
dotnfc 0:db8030e71f55 98 return 0;
dotnfc 0:db8030e71f55 99 }
dotnfc 0:db8030e71f55 100 va_end(arg);
dotnfc 0:db8030e71f55 101 r = BufferedSerial::write(buffer, r);
dotnfc 0:db8030e71f55 102
dotnfc 0:db8030e71f55 103 return r;
dotnfc 0:db8030e71f55 104 }
dotnfc 0:db8030e71f55 105
dotnfc 0:db8030e71f55 106 ssize_t BufferedSerial::write(const void *s, size_t length)
dotnfc 0:db8030e71f55 107 {
dotnfc 0:db8030e71f55 108 if (s != NULL && length > 0) {
dotnfc 0:db8030e71f55 109 const char* ptr = (const char*)s;
dotnfc 0:db8030e71f55 110 const char* end = ptr + length;
dotnfc 0:db8030e71f55 111
dotnfc 0:db8030e71f55 112 while (ptr != end) {
dotnfc 0:db8030e71f55 113 _txbuf = *(ptr++);
dotnfc 0:db8030e71f55 114 }
dotnfc 0:db8030e71f55 115 BufferedSerial::prime();
dotnfc 0:db8030e71f55 116
dotnfc 0:db8030e71f55 117 return ptr - (const char*)s;
dotnfc 0:db8030e71f55 118 }
dotnfc 0:db8030e71f55 119 return 0;
dotnfc 0:db8030e71f55 120 }
dotnfc 0:db8030e71f55 121
dotnfc 0:db8030e71f55 122
dotnfc 0:db8030e71f55 123 void BufferedSerial::rxIrq(void)
dotnfc 0:db8030e71f55 124 {
dotnfc 0:db8030e71f55 125 // read from the peripheral and make sure something is available
dotnfc 0:db8030e71f55 126 if(serial_readable(&_serial)) {
dotnfc 0:db8030e71f55 127 _rxbuf = serial_getc(&_serial); // if so load them into a buffer
dotnfc 0:db8030e71f55 128 }
dotnfc 0:db8030e71f55 129
dotnfc 0:db8030e71f55 130 return;
dotnfc 0:db8030e71f55 131 }
dotnfc 0:db8030e71f55 132
dotnfc 0:db8030e71f55 133 void BufferedSerial::txIrq(void)
dotnfc 0:db8030e71f55 134 {
dotnfc 0:db8030e71f55 135 // see if there is room in the hardware fifo and if something is in the software fifo
dotnfc 0:db8030e71f55 136 while(serial_writable(&_serial)) {
dotnfc 0:db8030e71f55 137 if(_txbuf.available()) {
dotnfc 0:db8030e71f55 138 serial_putc(&_serial, (int)_txbuf.get());
dotnfc 0:db8030e71f55 139 } else {
dotnfc 0:db8030e71f55 140 // disable the TX interrupt when there is nothing left to send
dotnfc 0:db8030e71f55 141 RawSerial::attach(NULL, RawSerial::TxIrq);
dotnfc 0:db8030e71f55 142 break;
dotnfc 0:db8030e71f55 143 }
dotnfc 0:db8030e71f55 144 }
dotnfc 0:db8030e71f55 145
dotnfc 0:db8030e71f55 146 return;
dotnfc 0:db8030e71f55 147 }
dotnfc 0:db8030e71f55 148
dotnfc 0:db8030e71f55 149 void BufferedSerial::prime(void)
dotnfc 0:db8030e71f55 150 {
dotnfc 0:db8030e71f55 151 // if already busy then the irq will pick this up
dotnfc 0:db8030e71f55 152 if(serial_writable(&_serial)) {
dotnfc 0:db8030e71f55 153 RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq
dotnfc 0:db8030e71f55 154 BufferedSerial::txIrq(); // only write to hardware in one place
dotnfc 0:db8030e71f55 155 RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
dotnfc 0:db8030e71f55 156 }
dotnfc 0:db8030e71f55 157
dotnfc 0:db8030e71f55 158 return;
dotnfc 0:db8030e71f55 159 }
dotnfc 0:db8030e71f55 160
dotnfc 0:db8030e71f55 161
dotnfc 0:db8030e71f55 162 size_t BufferedSerial::write(uint8_t val)
dotnfc 0:db8030e71f55 163 {
dotnfc 0:db8030e71f55 164 putc (val);
dotnfc 0:db8030e71f55 165 return 1;
dotnfc 0:db8030e71f55 166 }