Inherit from Serial and use software buffers for TX and RX. This allows the UART peripherals to operate in a IRQ driven mode. Overrides most (but not all) stdio functions as Serial did

Dependencies:   Buffer

Fork of BufferedSerial by Sam Grove

Committer:
sam_grove
Date:
Thu May 23 23:47:04 2013 +0000
Revision:
1:57a11fb5d529
Parent:
0:a977d0a3d81e
Child:
2:7e8a450a9101
Added prime (private member).Only want to pull from the buffer and write in one spot. prime stops irq's  and call the member txIrq to put the oldest buffered byte in the transmitter. IRQ will pull the rest out once enabled again.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 0:a977d0a3d81e 1 /**
sam_grove 0:a977d0a3d81e 2 * @file BufferedSerial.cpp
sam_grove 0:a977d0a3d81e 3 * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
sam_grove 0:a977d0a3d81e 4 * @author sam grove
sam_grove 0:a977d0a3d81e 5 * @version 1.0
sam_grove 0:a977d0a3d81e 6 * @see
sam_grove 0:a977d0a3d81e 7 *
sam_grove 0:a977d0a3d81e 8 * Copyright (c) 2013
sam_grove 0:a977d0a3d81e 9 *
sam_grove 0:a977d0a3d81e 10 * Licensed under the Apache License, Version 2.0 (the "License");
sam_grove 0:a977d0a3d81e 11 * you may not use this file except in compliance with the License.
sam_grove 0:a977d0a3d81e 12 * You may obtain a copy of the License at
sam_grove 0:a977d0a3d81e 13 *
sam_grove 0:a977d0a3d81e 14 * http://www.apache.org/licenses/LICENSE-2.0
sam_grove 0:a977d0a3d81e 15 *
sam_grove 0:a977d0a3d81e 16 * Unless required by applicable law or agreed to in writing, software
sam_grove 0:a977d0a3d81e 17 * distributed under the License is distributed on an "AS IS" BASIS,
sam_grove 0:a977d0a3d81e 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sam_grove 0:a977d0a3d81e 19 * See the License for the specific language governing permissions and
sam_grove 0:a977d0a3d81e 20 * limitations under the License.
sam_grove 0:a977d0a3d81e 21 */
sam_grove 0:a977d0a3d81e 22
sam_grove 0:a977d0a3d81e 23 #include "BufferedSerial.h"
sam_grove 0:a977d0a3d81e 24 #include "LogUtil.h"
sam_grove 0:a977d0a3d81e 25 #include <stdarg.h>
sam_grove 0:a977d0a3d81e 26
sam_grove 0:a977d0a3d81e 27 BufferedSerial::BufferedSerial(PinName tx, PinName rx, const char* name)
sam_grove 0:a977d0a3d81e 28 : Serial(tx, rx, name)
sam_grove 0:a977d0a3d81e 29 {
sam_grove 0:a977d0a3d81e 30 Serial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
sam_grove 0:a977d0a3d81e 31 Serial::attach(this, &BufferedSerial::txIrq, Serial::TxIrq);
sam_grove 0:a977d0a3d81e 32
sam_grove 0:a977d0a3d81e 33 return;
sam_grove 0:a977d0a3d81e 34 }
sam_grove 0:a977d0a3d81e 35
sam_grove 0:a977d0a3d81e 36 BufferedSerial::~BufferedSerial(void)
sam_grove 0:a977d0a3d81e 37 {
sam_grove 0:a977d0a3d81e 38 Serial::attach(NULL, Serial::RxIrq);
sam_grove 0:a977d0a3d81e 39 Serial::attach(NULL, Serial::TxIrq);
sam_grove 0:a977d0a3d81e 40
sam_grove 0:a977d0a3d81e 41 return;
sam_grove 0:a977d0a3d81e 42 }
sam_grove 0:a977d0a3d81e 43
sam_grove 0:a977d0a3d81e 44 int BufferedSerial::readable(void)
sam_grove 0:a977d0a3d81e 45 {
sam_grove 0:a977d0a3d81e 46 return _rxbuf.available(); // note: look if things are in the buffer
sam_grove 0:a977d0a3d81e 47 }
sam_grove 0:a977d0a3d81e 48
sam_grove 0:a977d0a3d81e 49 int BufferedSerial::writeable(void)
sam_grove 0:a977d0a3d81e 50 {
sam_grove 0:a977d0a3d81e 51 return 1; // buffer allows overwriting by design, always true
sam_grove 0:a977d0a3d81e 52 }
sam_grove 0:a977d0a3d81e 53
sam_grove 0:a977d0a3d81e 54 int BufferedSerial::getc(void)
sam_grove 0:a977d0a3d81e 55 {
sam_grove 0:a977d0a3d81e 56 return _rxbuf; // note: pulling from the buffer
sam_grove 0:a977d0a3d81e 57 }
sam_grove 0:a977d0a3d81e 58
sam_grove 0:a977d0a3d81e 59 int BufferedSerial::putc(int c)
sam_grove 0:a977d0a3d81e 60 {
sam_grove 0:a977d0a3d81e 61 _txbuf = (char)c;
sam_grove 1:57a11fb5d529 62 BufferedSerial::prime();
sam_grove 0:a977d0a3d81e 63
sam_grove 0:a977d0a3d81e 64 return c;
sam_grove 0:a977d0a3d81e 65 }
sam_grove 0:a977d0a3d81e 66
sam_grove 0:a977d0a3d81e 67 int BufferedSerial::puts(const char *s)
sam_grove 0:a977d0a3d81e 68 {
sam_grove 0:a977d0a3d81e 69 const char *size = s;
sam_grove 0:a977d0a3d81e 70
sam_grove 0:a977d0a3d81e 71 while(*(s) != 0)
sam_grove 0:a977d0a3d81e 72 {
sam_grove 0:a977d0a3d81e 73 _txbuf = *(s++);
sam_grove 0:a977d0a3d81e 74 }
sam_grove 1:57a11fb5d529 75 BufferedSerial::prime();
sam_grove 0:a977d0a3d81e 76
sam_grove 0:a977d0a3d81e 77 return s - size;
sam_grove 0:a977d0a3d81e 78 }
sam_grove 0:a977d0a3d81e 79
sam_grove 0:a977d0a3d81e 80 int BufferedSerial::printf(const char* format, ...)
sam_grove 0:a977d0a3d81e 81 {
sam_grove 0:a977d0a3d81e 82 char buf[256] = {0};
sam_grove 0:a977d0a3d81e 83 int r = 0;
sam_grove 0:a977d0a3d81e 84
sam_grove 0:a977d0a3d81e 85 va_list arg;
sam_grove 0:a977d0a3d81e 86 va_start(arg, format);
sam_grove 0:a977d0a3d81e 87 r = vsprintf(buf, format, arg);
sam_grove 0:a977d0a3d81e 88 // this may not hit the heap but should alert the user anyways
sam_grove 0:a977d0a3d81e 89 if(r > sizeof(buf))
sam_grove 0:a977d0a3d81e 90 {
sam_grove 0:a977d0a3d81e 91 ERROR("Buffer Overwrite Occured!\n");
sam_grove 0:a977d0a3d81e 92 }
sam_grove 0:a977d0a3d81e 93 r = BufferedSerial::puts(buf);
sam_grove 0:a977d0a3d81e 94 va_end(arg);
sam_grove 0:a977d0a3d81e 95
sam_grove 0:a977d0a3d81e 96 return r;
sam_grove 0:a977d0a3d81e 97 }
sam_grove 0:a977d0a3d81e 98
sam_grove 0:a977d0a3d81e 99 void BufferedSerial::rxIrq(void)
sam_grove 0:a977d0a3d81e 100 {
sam_grove 0:a977d0a3d81e 101 // read from the peripheral and see if things are available
sam_grove 0:a977d0a3d81e 102 while(serial_readable(&_serial))
sam_grove 0:a977d0a3d81e 103 {
sam_grove 0:a977d0a3d81e 104 _rxbuf = serial_getc(&_serial); // if so load them into a buffer
sam_grove 0:a977d0a3d81e 105 }
sam_grove 0:a977d0a3d81e 106
sam_grove 0:a977d0a3d81e 107 return;
sam_grove 0:a977d0a3d81e 108 }
sam_grove 0:a977d0a3d81e 109
sam_grove 0:a977d0a3d81e 110 void BufferedSerial::txIrq(void)
sam_grove 0:a977d0a3d81e 111 {
sam_grove 0:a977d0a3d81e 112 // see if there is room in the hardware buffer and something is in the software buffer
sam_grove 0:a977d0a3d81e 113 while(serial_writable(&_serial) && _txbuf.available())
sam_grove 0:a977d0a3d81e 114 {
sam_grove 0:a977d0a3d81e 115 serial_putc(&_serial, (int)_txbuf.get());
sam_grove 0:a977d0a3d81e 116 }
sam_grove 0:a977d0a3d81e 117
sam_grove 0:a977d0a3d81e 118 return;
sam_grove 0:a977d0a3d81e 119 }
sam_grove 0:a977d0a3d81e 120
sam_grove 1:57a11fb5d529 121 void BufferedSerial::prime(void)
sam_grove 1:57a11fb5d529 122 {
sam_grove 1:57a11fb5d529 123 __disable_irq(); // make sure not to cause contention in the irq
sam_grove 1:57a11fb5d529 124 BufferedSerial::txIrq(); // prime the txirq to stoke transmit
sam_grove 1:57a11fb5d529 125 __enable_irq();
sam_grove 1:57a11fb5d529 126
sam_grove 1:57a11fb5d529 127 return;
sam_grove 1:57a11fb5d529 128 }
sam_grove 0:a977d0a3d81e 129
sam_grove 0:a977d0a3d81e 130
sam_grove 1:57a11fb5d529 131