Infrared SoftSerial. Use CircularBuffer.
Dependents: Test_SoftSerial_Infrared
Revision 13:f3f6c1bc3bd6, committed 2020-05-15
- Comitter:
- kenjiArai
- Date:
- Fri May 15 04:12:42 2020 +0000
- Parent:
- 12:7ab9ab7210e7
- Commit message:
- Infrared SoftSeral (bufferred)
Changed in this revision
diff -r 7ab9ab7210e7 -r f3f6c1bc3bd6 Bf_SoftSerial_IR.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Bf_SoftSerial_IR.cpp Fri May 15 04:12:42 2020 +0000 @@ -0,0 +1,151 @@ +/** + * @file BufferedSoftSerial.cpp + * @brief Software Buffer + * - Extends mbed Serial functionallity adding irq driven TX and RX + * @author sam grove + * @version 1.0 + * @see + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Modified by K.Arai / JH1PJL May 15th, 2020 + +#include "Bf_SoftSerial_IR.h" +#include <stdarg.h> + +Bf_SoftSerial_IR::Bf_SoftSerial_IR(PinName tx, PinName rx, const char* name) + : SoftSerial_IR(tx, rx, name) +{ + _rxbuf.reset(); + _txbuf.reset(); + SoftSerial_IR::attach( + this, &Bf_SoftSerial_IR::rx_Irq, SoftSerial_IR::RxIrq + ); + return; +} + +int Bf_SoftSerial_IR::readable(void) +{ + return !_rxbuf.empty(); +} + +int Bf_SoftSerial_IR::writeable(void) +{ + return _txbuf.full(); +} + +int Bf_SoftSerial_IR::getc(void) +{ + char c; + while(_rxbuf.empty()) { + ; + } + _rxbuf.pop(c); + return c; +} + +int Bf_SoftSerial_IR::putc(int c) +{ + _txbuf.push((char)c); + prime(); + return c; +} + +int Bf_SoftSerial_IR::puts(const char *s) +{ + const char* ptr = s; + + while(*(ptr) != 0) { + _txbuf.push(*(ptr++)); + } +#if 0 + _txbuf.push('\n'); // done per puts definition +#endif + prime(); + return (ptr - s) + 1; +} + +int Bf_SoftSerial_IR::printf(const char* format, ...) +{ + char buf[256] = {0}; + int r = 0; + + va_list arg; + va_start(arg, format); + r = vsprintf(buf, format, arg); + // this may not hit the heap but should alert the user anyways + if(r > sizeof(buf)) { + error("%s %d buffer overwrite!\n", __FILE__, __LINE__); + } + va_end(arg); + r = write(buf, r); + return r; +} + +ssize_t Bf_SoftSerial_IR::write(const void *s, size_t length) +{ + const char* ptr = (const char*)s; + const char* end = ptr + length; + + while (ptr != end) { + _txbuf.push(*(ptr++)); + } + prime(); + return ptr - (const char*)s; +} + + +void Bf_SoftSerial_IR::rx_Irq(void) +{ + // read from the peripheral and make sure something is available + if(SoftSerial_IR::readable()) { + _rxbuf.push(_getc()); // if so load them into a buffer + } + return; +} + +void Bf_SoftSerial_IR::tx_Irq(void) +{ + // see if there is room in the hardware fifo and + // if something is in the software fifo + while(SoftSerial_IR::writeable()) { + if(!_txbuf.empty()) { + char c; + _txbuf.pop(c); + _putc((int)c); + } else { + // disable the TX interrupt when there is nothing left to send + SoftSerial_IR::attach(NULL, SoftSerial_IR::TxIrq); + break; + } + } + return; +} + +void Bf_SoftSerial_IR::prime(void) +{ + // if already busy then the irq will pick this up + if(SoftSerial_IR::writeable()) { + // make sure not to cause contention in the irq + SoftSerial_IR::attach(NULL, SoftSerial_IR::TxIrq); + // only write to hardware in one place + tx_Irq(); + SoftSerial_IR::attach( + this,&Bf_SoftSerial_IR::tx_Irq,SoftSerial_IR::TxIrq + ); + } + return; +}
diff -r 7ab9ab7210e7 -r f3f6c1bc3bd6 Bf_SoftSerial_IR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Bf_SoftSerial_IR.h Fri May 15 04:12:42 2020 +0000 @@ -0,0 +1,153 @@ + +/** + * @file BufferedSoftSerial.h + * @brief Software Buffer + * - Extends mbed Serial functionallity adding irq driven TX and RX + * @author sam grove + * @version 1.0 + * @see + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + Original Library by Erik- + https://os.mbed.com/users/Sissors/code/BufferedSoftSerial/ + + Modified by K.Arai / JH1PJL May 15th, 2020 + + modified parts + use CircularBuffer (mbed standard library) + */ + +#ifndef BUFFEREDSOFTSERIAL_H +#define BUFFEREDSOFTSERIAL_H + +#include "mbed.h" +#include "SoftSerial_IR.h" + +/** A serial port (UART) for communication with other serial devices + * + * Can be used for Full Duplex communication, or Simplex by specifying + * one pin as NC (Not Connected) + * + * This uses software serial emulation, regular serial pins are alot better, + * however if you don't have spare ones, you can use this. It is advicable + * to put the serial connection with highest speed to hardware serial. + * + * If you lack RAM memory you can also use SoftSerial + * without this buffer around it. + * In that case it is fully blocking. + * + * Example: + * @code + * #include "mbed.h" + * #include "BufferedSoftSerial.h" + * + * SoftSerial block(USBTX, USBRX); + * BufferedSoftSerial buf(D3, D2); + * + * int main() + * { + * while(1) { + * Timer s; + * + * s.start(); + * buf.printf("Hello World - buffered\r\n"); + * int buffered_time = s.read_us(); + * wait(0.1f); // give time for the buffer to empty + * + * s.reset(); + * block.printf("Hello World - blocking\r\n"); + * int polled_time = s.read_us(); + * s.stop(); + * wait(0.1f); // give time for the buffer to empty + * + * buf.printf("printf buffered took %d us\r\n", buffered_time); + * buf.printf("printf blocking took %d us\r\n", polled_time); + * wait(5); + * } + * } + * @endcode + */ + +/** + * @class BufferedSerial + * @brief Software buffers and interrupt driven tx and rx for SoftSerial + */ +class Bf_SoftSerial_IR : public SoftSerial_IR +{ +private: + CircularBuffer<char, 256> _rxbuf; + CircularBuffer<char, 256> _txbuf; + + void rx_Irq(void); + void tx_Irq(void); + void prime(void); + +public: + /** Create a BufferedSoftSerial port, + * connected to the specified transmit and receive pins + * @param tx Transmit pin + * @param rx Receive pin + * @note Either tx or rx may be specified as NC if unused + */ + Bf_SoftSerial_IR(PinName tx, PinName rx, const char* name=NULL); + + /** Check on how many bytes are in the rx buffer + * @return 1 if something exists, 0 otherwise + */ + virtual int readable(void); + + /** Check to see if the tx buffer has room + * @return 1 always has room and can overwrite previous content + * if too small / slow + */ + virtual int writeable(void); + + /** Get a single byte from the BufferedSoftSerial Port. + * Should check readable() before calling this. + * @return A byte that came in on the BufferedSoftSerial Port + */ + virtual int getc(void); + + /** Write a single byte to the BufferedSoftSerial Port. + * @param c The byte to write to the BufferedSoftSerial Port + * @return The byte that was written to the BufferedSoftSerial Port Buffer + */ + virtual int putc(int c); + + /** Write a string to the BufferedSoftSerial Port. Must be NULL terminated + * @param s The string to write to the Serial Port + * @return The number of bytes written to the Serial Port Buffer + */ + virtual int puts(const char *s); + + /** Write a formatted string to the BufferedSoftSerial Port. + * @param format The string + format specifiers to write + * to the BufferedSoftSerial Port + * @return The number of bytes written to the Serial Port Buffer + */ + virtual int printf(const char* format, ...); + + /** Write data to the BufferedSoftSerial Port + * @param s A pointer to data to send + * @param length The amount of data being pointed to + * @return The number of bytes written to the Serial Port Buffer + */ + virtual ssize_t write(const void *s, std::size_t length); +}; + +#endif
diff -r 7ab9ab7210e7 -r f3f6c1bc3bd6 BufferedSoftSerial.cpp --- a/BufferedSoftSerial.cpp Tue May 12 05:28:37 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/** - * @file BufferedSoftSerial.cpp - * @brief Software Buffer - * - Extends mbed Serial functionallity adding irq driven TX and RX - * @author sam grove - * @version 1.0 - * @see - * - * Copyright (c) 2013 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Modified by K.Arai / JH1PJL May 12th, 2020 - -#include "BufferedSoftSerial.h" -#include <stdarg.h> - -BufferedSoftSerial::BufferedSoftSerial(PinName tx, PinName rx, const char* name) - : SoftSerial(tx, rx, name) -{ - _rxbuf.reset(); - _txbuf.reset(); - SoftSerial::attach(this, &BufferedSoftSerial::rx_Irq, SoftSerial::RxIrq); - return; -} - -int BufferedSoftSerial::readable(void) -{ - return !_rxbuf.empty(); -} - -int BufferedSoftSerial::writeable(void) -{ - return _txbuf.full(); -} - -int BufferedSoftSerial::getc(void) -{ - char c; - while(_rxbuf.empty()) { - ; - } - _rxbuf.pop(c); - return c; -} - -int BufferedSoftSerial::putc(int c) -{ - _txbuf.push((char)c); - prime(); - return c; -} - -int BufferedSoftSerial::puts(const char *s) -{ - const char* ptr = s; - - while(*(ptr) != 0) { - _txbuf.push(*(ptr++)); - } -#if 0 - _txbuf.push('\n'); // done per puts definition -#endif - prime(); - return (ptr - s) + 1; -} - -int BufferedSoftSerial::printf(const char* format, ...) -{ - char buf[256] = {0}; - int r = 0; - - va_list arg; - va_start(arg, format); - r = vsprintf(buf, format, arg); - // this may not hit the heap but should alert the user anyways - if(r > sizeof(buf)) { - error("%s %d buffer overwrite!\n", __FILE__, __LINE__); - } - va_end(arg); - r = write(buf, r); - return r; -} - -ssize_t BufferedSoftSerial::write(const void *s, size_t length) -{ - const char* ptr = (const char*)s; - const char* end = ptr + length; - - while (ptr != end) { - _txbuf.push(*(ptr++)); - } - prime(); - return ptr - (const char*)s; -} - - -void BufferedSoftSerial::rx_Irq(void) -{ - // read from the peripheral and make sure something is available - if(SoftSerial::readable()) { - _rxbuf.push(_getc()); // if so load them into a buffer - } - return; -} - -void BufferedSoftSerial::tx_Irq(void) -{ - // see if there is room in the hardware fifo and - // if something is in the software fifo - while(SoftSerial::writeable()) { - if(!_txbuf.empty()) { - char c; - _txbuf.pop(c); - _putc((int)c); - } else { - // disable the TX interrupt when there is nothing left to send - SoftSerial::attach(NULL, SoftSerial::TxIrq); - break; - } - } - return; -} - -void BufferedSoftSerial::prime(void) -{ - // if already busy then the irq will pick this up - if(SoftSerial::writeable()) { - // make sure not to cause contention in the irq - SoftSerial::attach(NULL, SoftSerial::TxIrq); - // only write to hardware in one place - tx_Irq(); - SoftSerial::attach(this,&BufferedSoftSerial::tx_Irq,SoftSerial::TxIrq); - } - return; -}
diff -r 7ab9ab7210e7 -r f3f6c1bc3bd6 BufferedSoftSerial.h --- a/BufferedSoftSerial.h Tue May 12 05:28:37 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ - -/** - * @file BufferedSoftSerial.h - * @brief Software Buffer - * - Extends mbed Serial functionallity adding irq driven TX and RX - * @author sam grove - * @version 1.0 - * @see - * - * Copyright (c) 2013 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - Original Library by Erik- - https://os.mbed.com/users/Sissors/code/BufferedSoftSerial/ - - Modified by K.Arai / JH1PJL May 12th, 2020 - - modified parts - use CircularBuffer (mbed standard library) - */ - -#ifndef BUFFEREDSOFTSERIAL_H -#define BUFFEREDSOFTSERIAL_H - -#include "mbed.h" -#include "SoftSerial.h" - -/** A serial port (UART) for communication with other serial devices - * - * Can be used for Full Duplex communication, or Simplex by specifying - * one pin as NC (Not Connected) - * - * This uses software serial emulation, regular serial pins are alot better, - * however if you don't have spare ones, you can use this. It is advicable - * to put the serial connection with highest speed to hardware serial. - * - * If you lack RAM memory you can also use SoftSerial - * without this buffer around it. - * In that case it is fully blocking. - * - * Example: - * @code - * #include "mbed.h" - * #include "BufferedSoftSerial.h" - * - * SoftSerial block(USBTX, USBRX); - * BufferedSoftSerial buf(D3, D2); - * - * int main() - * { - * while(1) { - * Timer s; - * - * s.start(); - * buf.printf("Hello World - buffered\r\n"); - * int buffered_time = s.read_us(); - * wait(0.1f); // give time for the buffer to empty - * - * s.reset(); - * block.printf("Hello World - blocking\r\n"); - * int polled_time = s.read_us(); - * s.stop(); - * wait(0.1f); // give time for the buffer to empty - * - * buf.printf("printf buffered took %d us\r\n", buffered_time); - * buf.printf("printf blocking took %d us\r\n", polled_time); - * wait(5); - * } - * } - * @endcode - */ - -/** - * @class BufferedSerial - * @brief Software buffers and interrupt driven tx and rx for SoftSerial - */ -class BufferedSoftSerial : public SoftSerial -{ -private: - CircularBuffer<char, 256> _rxbuf; - CircularBuffer<char, 256> _txbuf; - - void rx_Irq(void); - void tx_Irq(void); - void prime(void); - -public: - /** Create a BufferedSoftSerial port, - * connected to the specified transmit and receive pins - * @param tx Transmit pin - * @param rx Receive pin - * @note Either tx or rx may be specified as NC if unused - */ - BufferedSoftSerial(PinName tx, PinName rx, const char* name=NULL); - - /** Check on how many bytes are in the rx buffer - * @return 1 if something exists, 0 otherwise - */ - virtual int readable(void); - - /** Check to see if the tx buffer has room - * @return 1 always has room and can overwrite previous content - * if too small / slow - */ - virtual int writeable(void); - - /** Get a single byte from the BufferedSoftSerial Port. - * Should check readable() before calling this. - * @return A byte that came in on the BufferedSoftSerial Port - */ - virtual int getc(void); - - /** Write a single byte to the BufferedSoftSerial Port. - * @param c The byte to write to the BufferedSoftSerial Port - * @return The byte that was written to the BufferedSoftSerial Port Buffer - */ - virtual int putc(int c); - - /** Write a string to the BufferedSoftSerial Port. Must be NULL terminated - * @param s The string to write to the Serial Port - * @return The number of bytes written to the Serial Port Buffer - */ - virtual int puts(const char *s); - - /** Write a formatted string to the BufferedSoftSerial Port. - * @param format The string + format specifiers to write - * to the BufferedSoftSerial Port - * @return The number of bytes written to the Serial Port Buffer - */ - virtual int printf(const char* format, ...); - - /** Write data to the BufferedSoftSerial Port - * @param s A pointer to data to send - * @param length The amount of data being pointed to - * @return The number of bytes written to the Serial Port Buffer - */ - virtual ssize_t write(const void *s, std::size_t length); -}; - -#endif
diff -r 7ab9ab7210e7 -r f3f6c1bc3bd6 SoftSerial.lib --- a/SoftSerial.lib Tue May 12 05:28:37 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://os.mbed.com/users/kenjiArai/code/SoftSerial/#6399b30798a5
diff -r 7ab9ab7210e7 -r f3f6c1bc3bd6 SoftSerial_IR.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SoftSerial_IR.lib Fri May 15 04:12:42 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/kenjiArai/code/SoftSerial_IR/#8d343be3382d