Infrared SoftSerial. Use CircularBuffer.

Dependencies:   SoftSerial_IR

Dependents:   Test_SoftSerial_Infrared

Committer:
kenjiArai
Date:
Fri May 15 04:12:42 2020 +0000
Revision:
13:f3f6c1bc3bd6
Infrared SoftSeral (bufferred)

Who changed what in which revision?

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