From 8b583f596109bb97e0d7b8ef773c6fff96d31d34 Mon Sep 17 00:00:00 2001 From: oclyke Date: Thu, 23 Jul 2020 17:23:19 -0600 Subject: [PATCH] support hardware serial provides a default UART object 'Serial' through which the console is routed allows additional UART objects on other pins --- core-extend/ArduinoAPI.h | 1 + core-extend/HardwareSerial.h | 62 +++++++++++ core-implement/HardwareSerial.cpp | 178 ++++++++++++++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 core-extend/HardwareSerial.h create mode 100644 core-implement/HardwareSerial.cpp diff --git a/core-extend/ArduinoAPI.h b/core-extend/ArduinoAPI.h index 98c31d1..f824bc9 100644 --- a/core-extend/ArduinoAPI.h +++ b/core-extend/ArduinoAPI.h @@ -24,5 +24,6 @@ SOFTWARE. #define _ARDUINO_MBED_BRIDGE_CORE_EXTEND_ARDUINOAPI_H_ #include "core-extend/Common.h" +#include "core-extend/HardwareSerial.h" #endif // _ARDUINO_MBED_BRIDGE_CORE_EXTEND_ARDUINOAPI_H_ diff --git a/core-extend/HardwareSerial.h b/core-extend/HardwareSerial.h new file mode 100644 index 0000000..92bd1e5 --- /dev/null +++ b/core-extend/HardwareSerial.h @@ -0,0 +1,62 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef _ARDUINO_MBED_BRIDGE_CORE_EXTEND_HARDWARESERIAL_H_ +#define _ARDUINO_MBED_BRIDGE_CORE_EXTEND_HARDWARESERIAL_H_ + +#include "bridge/pins.h" +#include "core-api/api/RingBuffer.h" + +#define RX_BUF_LEN (256) + +class UART : public HardwareSerial, public mbed::UnbufferedSerial { +private: + RingBufferN _rxbuf; + +protected: +public: + UART(PinName tx, PinName rx, PinName rts = NC, PinName cts = NC); + UART(pin_size_t tx, pin_size_t rx, pin_size_t rts = variantPinCount, pin_size_t cts = variantPinCount); + UART( void ); + ~UART( void ); + + void rxISR( void ); + + void begin(unsigned long baudrate, uint16_t config); + void begin(unsigned long baudrate); + void end( void ); + int available(void); + int peek(void); + int read(void); + void flush(void); + size_t write(uint8_t c); + size_t write(const uint8_t* buffer, size_t size); + using Print::write; + int printf(const char *format, ...); + operator bool(){ + return true; + } +}; + +extern UART Serial; + +#endif // _ARDUINO_MBED_BRIDGE_CORE_EXTEND_HARDWARESERIAL_H_ diff --git a/core-implement/HardwareSerial.cpp b/core-implement/HardwareSerial.cpp new file mode 100644 index 0000000..b32daad --- /dev/null +++ b/core-implement/HardwareSerial.cpp @@ -0,0 +1,178 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "core-extend/HardwareSerial.h" + +UART Serial; + +// redirect stdout / stdin to Serial +FileHandle *mbed::mbed_override_console(int) +{ + return (FileHandle*)&Serial; +} + +UART::UART(PinName tx, PinName rx, PinName rts, PinName cts) : + UnbufferedSerial(tx, rx) +{ +#ifdef DEVICE_SERIAL_FC + mbed::SerialBase::Flow control = mbed::SerialBase::Disabled; + PinName flow1 = rts; + pinName flow2 = cts; + bool has_rts = (rts != NC); + bool has_cts = (cts != NC); + if(has_rts && has_cts){ + control = mbed::SerialBase::RTSCTS; + }else{ + if(has_rts){ + control = mbed::SerialBase::RTS; + flow1 = rts; + } + if(has_cts){ + control = mbed::SerialBase::CTS; + flow1 = cts; + } + } + BufferedSerial::set_flow_control(control, flow1, flow2); +#endif // DEVICE_SERIAL_FC +} + +UART::UART(pin_size_t tx, pin_size_t rx, pin_size_t rts, pin_size_t cts) : + UART(pinNameByNumber(tx), pinNameByNumber(rx), pinNameByNumber(rts), pinNameByNumber(cts)) +{ + +} + +UART::UART( void ) : + UART(STDIO_UART_TX, STDIO_UART_RX) +{ + +} + +UART::~UART( void ){ + +} + +void UART::rxISR( void ){ + char c; + while(UnbufferedSerial::readable()) { + UnbufferedSerial::read(&c, 1); + _rxbuf.store_char(c); + } +} + +void UART::begin(unsigned long baudrate, uint16_t config){ + mbed::SerialBase::Parity parity; + int stop_bits; + int bits; + + switch(config & SERIAL_PARITY_MASK){ + case SERIAL_PARITY_EVEN : parity = mbed::SerialBase::Even; break; + case SERIAL_PARITY_ODD : parity = mbed::SerialBase::Odd; break; + case SERIAL_PARITY_MARK : parity = mbed::SerialBase::Forced1; break; + case SERIAL_PARITY_SPACE : parity = mbed::SerialBase::Forced0; break; + case SERIAL_PARITY_NONE : + default : + parity = mbed::SerialBase::None; + break; + } + + switch(config & SERIAL_STOP_BIT_MASK){ + case SERIAL_STOP_BIT_1_5 : + case SERIAL_STOP_BIT_2 : + stop_bits = 2; + break; + case SERIAL_STOP_BIT_1 : + default : + stop_bits = 1; + break; + } + + switch(config & SERIAL_DATA_MASK){ + case SERIAL_DATA_5 : bits = 5; break; + case SERIAL_DATA_6 : bits = 6; break; + case SERIAL_DATA_7 : bits = 7; break; + case SERIAL_DATA_8 : + default : + bits = 8; + break; + } + + // disable that pesky FIFO + AM_CRITICAL_BEGIN + UARTn(0)->LCRH_b.FEN = 0; + UARTn(1)->LCRH_b.FEN = 0; + AM_CRITICAL_END + + mbed::UnbufferedSerial::set_blocking (false); + mbed::UnbufferedSerial::baud((int)baudrate); + mbed::UnbufferedSerial::format(bits, parity, stop_bits); + mbed::UnbufferedSerial::attach(mbed::callback(this, &UART::rxISR), mbed::UnbufferedSerial::RxIrq); +} + +void UART::begin(unsigned long baudrate){ + begin(baudrate, SERIAL_8N1); +} + +void UART::end( void ){ + +} + +int UART::available(void){ + return _rxbuf.available(); +} + +int UART::peek(void){ + return _rxbuf.peek(); +} + +int UART::read(void){ + return _rxbuf.read_char(); +} + +void UART::flush(void){ + +} + +size_t UART::write(uint8_t c){ + return write(&c, 1); +} + +size_t UART::write(const uint8_t* buffer, size_t size){ + while (!UnbufferedSerial::writeable()){}; + int result = UnbufferedSerial::write((void*)buffer, size); + return (result < 0) ? 0 : result; +} + +int UART::printf(const char *format, ...){ + + va_list args; + va_start(args, format); + const int space = vsnprintf(NULL, 0, format, args) + 1; + char buf[space]; + memset(buf, 0x00, space); + vsnprintf(buf, space, format, args); + va_end(args); + + int size = strlen(buf); + write(buf, size); + return size; +}