From 80a55a037b09083940b8b589515f9da2271d8ad2 Mon Sep 17 00:00:00 2001 From: Franck Roudet Date: Mon, 9 Apr 2018 17:19:28 +0200 Subject: [PATCH 1/2] private become protected so ease overriding --- CmdMessenger.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CmdMessenger.h b/CmdMessenger.h index 1072bd7..b1b3ad9 100644 --- a/CmdMessenger.h +++ b/CmdMessenger.h @@ -58,8 +58,8 @@ enum class CmdMessenger { -private: - // **** Private variables *** +protected: + // **** Protected variables *** bool startCommand; // Indicates if sending of a command is underway uint8_t lastCommandId; // ID of last received command From df345ff62fac5854bd479da645e33620171ead1c Mon Sep 17 00:00:00 2001 From: Franck Roudet Date: Fri, 14 Sep 2018 11:33:54 +0200 Subject: [PATCH 2/2] Mbed compatible, not tested --- CmdMessenger.cpp | 40 +++++++++++++++-------- CmdMessenger.h | 82 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 90 insertions(+), 32 deletions(-) diff --git a/CmdMessenger.cpp b/CmdMessenger.cpp index cbb4ee7..3ecf523 100644 --- a/CmdMessenger.cpp +++ b/CmdMessenger.cpp @@ -50,12 +50,26 @@ extern "C" { #define _CMDMESSENGER_VERSION 3_6 // software version of this library -// **** Initialization **** +#if defined(__MBED__) || defined(MBED_STREAM_H) +#define BYTEAVAILLABLE(comms) comms->readable() +#define READONECHAR(comms) comms->getc() +#define PRINTONECHAR(comms,c) comms->putc(c) +#define PRINTSTRING(comms,s) comms->puts(s) +#define millis() (us_ticker_read()/1000) +#endif +#if defined(ARDUINO) && !defined(MBED_STREAM_H) +#define BYTEAVAILLABLE(comms) comms->available() +#define READONECHAR(comms) comms->read() +#define PRINTONECHAR(comms,c) comms->print(c) +#define PRINTSTRING(comms,s) comms->print(s) +#endif + +// **** Initialization **** /** * CmdMessenger constructor */ -CmdMessenger::CmdMessenger(Stream &ccomms, const char fld_separator, const char cmd_separator, const char esc_character) +CmdMessenger::CmdMessenger(__DEVICESTREAMTYPE &ccomms, const char fld_separator, const char cmd_separator, const char esc_character) { init(ccomms, fld_separator, cmd_separator, esc_character); } @@ -63,7 +77,7 @@ CmdMessenger::CmdMessenger(Stream &ccomms, const char fld_separator, const char /** * Enables printing newline after a sent command */ -void CmdMessenger::init(Stream &ccomms, const char fld_separator, const char cmd_separator, const char esc_character) +void CmdMessenger::init(__DEVICESTREAMTYPE &ccomms, const char fld_separator, const char cmd_separator, const char esc_character) { default_callback = NULL; comms = &ccomms; @@ -112,7 +126,7 @@ void CmdMessenger::attach(messengerCallbackFunction newFunction) /** * Attaches a function to a command ID */ -void CmdMessenger::attach(byte msgId, messengerCallbackFunction newFunction) +void CmdMessenger::attach(CmdMsgByte msgId, messengerCallbackFunction newFunction) { if (msgId >= 0 && msgId < MAXCALLBACKS) callbackList[msgId] = newFunction; @@ -127,7 +141,7 @@ void CmdMessenger::feedinSerialData() { while (!pauseProcessing && comms->available()) { - // The Stream class has a readBytes() function that reads many bytes at once. On Teensy 2.0 and 3.0, readBytes() is optimized. + // The Stream class has a readBytes() function that reads many bytes at once. On Teensy 2.0 and 3.0, readBytes() is optimized. // Benchmarks about the incredible difference it makes: http://www.pjrc.com/teensy/benchmark_usb_serial_receive.html size_t bytesAvailable = min(comms->available(), MAXSTREAMBUFFERSIZE); @@ -188,7 +202,7 @@ void CmdMessenger::handleMessage() /** * Waits for reply from sender or timeout before continuing */ -bool CmdMessenger::blockedTillReply(unsigned int timeout, byte ackCmdId) +bool CmdMessenger::blockedTillReply(unsigned int timeout, CmdMsgByte ackCmdId) { unsigned long time = millis(); unsigned long start = time; @@ -203,10 +217,10 @@ bool CmdMessenger::blockedTillReply(unsigned int timeout, byte ackCmdId) /** * Loops as long data is available to determine if acknowledge has come in */ -bool CmdMessenger::checkForAck(byte ackCommand) +bool CmdMessenger::checkForAck(CmdMsgByte ackCommand) { while (comms->available()) { - //Processes a byte and determines if an acknowlegde has come in + //Processes a CmdMsgByte and determines if an acknowlegde has come in int messageState = processLine(comms->read()); if (messageState == kEndOfMessage) { int id = readInt16Arg(); @@ -275,7 +289,7 @@ uint8_t CmdMessenger::commandID() /** * Send start of command. This makes it easy to send multiple arguments per command */ -void CmdMessenger::sendCmdStart(byte cmdId) +void CmdMessenger::sendCmdStart(CmdMsgByte cmdId) { if (!startCommand) { startCommand = true; @@ -330,7 +344,7 @@ void CmdMessenger::sendCmdSciArg(double arg, unsigned int n) /** * Send end of command */ -bool CmdMessenger::sendCmdEnd(bool reqAc, byte ackCmdId, unsigned int timeout) +bool CmdMessenger::sendCmdEnd(bool reqAc, CmdMsgByte ackCmdId, unsigned int timeout) { bool ackReply = false; if (startCommand) { @@ -349,7 +363,7 @@ bool CmdMessenger::sendCmdEnd(bool reqAc, byte ackCmdId, unsigned int timeout) /** * Send a command without arguments, with acknowledge */ -bool CmdMessenger::sendCmd(byte cmdId, bool reqAc, byte ackCmdId) +bool CmdMessenger::sendCmd(CmdMsgByte cmdId, bool reqAc, CmdMsgByte ackCmdId) { if (!startCommand) { sendCmdStart(cmdId); @@ -361,7 +375,7 @@ bool CmdMessenger::sendCmd(byte cmdId, bool reqAc, byte ackCmdId) /** * Send a command without arguments, without acknowledge */ -bool CmdMessenger::sendCmd(byte cmdId) +bool CmdMessenger::sendCmd(CmdMsgByte cmdId) { if (!startCommand) { sendCmdStart(cmdId); @@ -675,4 +689,4 @@ void CmdMessenger::printSci(double f, unsigned int digits) char output[16]; sprintf(output, format, whole, part, exponent); comms->print(output); -} \ No newline at end of file +} diff --git a/CmdMessenger.h b/CmdMessenger.h index b1b3ad9..02a00be 100644 --- a/CmdMessenger.h +++ b/CmdMessenger.h @@ -32,6 +32,22 @@ #include #endif +#if defined(__MBED__) +#include +#endif + +#if defined(MBED_STREAM_H) +/** Mbed platform compatibility and mbed like Stream**/ +/** #include */ + +#define __DEVICESTREAMTYPE UARTClass +#define CmdMsgByte uint8_t +#endif +#if defined(ARDUINO) && !defined(MBED_STREAM_H) +#define __DEVICESTREAMTYPE Stream +#define CmdMsgByte byte +#endif + //#include "Stream.h" extern "C" @@ -78,7 +94,7 @@ class CmdMessenger char *current; // Pointer to current buffer position char *last; // Pointer to previous buffer position char prevChar; // Previous char (needed for unescaping) - Stream *comms; // Serial data stream + __DEVICESTREAMTYPE *comms; // Serial data stream char command_separator; // Character indicating end of command (default: ';') char field_separator; // Character indicating end of argument (default: ',') @@ -90,15 +106,15 @@ class CmdMessenger // **** Initialize **** - void init(Stream & comms, const char fld_separator, const char cmd_separator, const char esc_character); + void init(__DEVICESTREAMTYPE & comms, const char fld_separator, const char cmd_separator, const char esc_character); void reset(); // **** Command processing **** inline uint8_t processLine(char serialChar) __attribute__((always_inline)); inline void handleMessage() __attribute__((always_inline)); - inline bool blockedTillReply(unsigned int timeout = DEFAULT_TIMEOUT, byte ackCmdId = 1) __attribute__((always_inline)); - inline bool checkForAck(byte AckCommand) __attribute__((always_inline)); + inline bool blockedTillReply(unsigned int timeout = DEFAULT_TIMEOUT, CmdMsgByte ackCmdId = 1) __attribute__((always_inline)); + inline bool checkForAck(CmdMsgByte AckCommand) __attribute__((always_inline)); // **** Command sending **** @@ -108,7 +124,7 @@ class CmdMessenger template < class T > void writeBin(const T & value) { - const byte *bytePointer = (const byte *)(const void *)&value; + const CmdMsgByte *bytePointer = (const CmdMsgByte *)(const void *)&value; for (unsigned int i = 0; i < sizeof(value); i++) { printEsc(*bytePointer); @@ -128,7 +144,7 @@ class CmdMessenger { T value; unescape(str); - byte *bytePointer = (byte *)(const void *)&value; + CmdMsgByte *bytePointer = (CmdMsgByte *)(const void *)&value; for (unsigned int i = 0; i < sizeof(value); i++) { *bytePointer = str[i]; @@ -141,7 +157,7 @@ class CmdMessenger T empty() { T value; - byte *bytePointer = (byte *)(const void *)&value; + CmdMsgByte *bytePointer = (CmdMsgByte *)(const void *)&value; for (unsigned int i = 0; i < sizeof(value); i++) { *bytePointer = '\0'; @@ -164,13 +180,13 @@ class CmdMessenger // **** Initialization **** - CmdMessenger(Stream & comms, const char fld_separator = ',', + CmdMessenger(__DEVICESTREAMTYPE & comms, const char fld_separator = ',', const char cmd_separator = ';', const char esc_character = '/'); void printLfCr(bool addNewLine = true); void attach(messengerCallbackFunction newFunction); - void attach(byte msgId, messengerCallbackFunction newFunction); + void attach(CmdMsgByte msgId, messengerCallbackFunction newFunction); // **** Command processing **** @@ -187,7 +203,7 @@ class CmdMessenger * Note that the argument is sent as string */ template < class T > - bool sendCmd(byte cmdId, T arg, bool reqAc = false, byte ackCmdId = 1, + bool sendCmd(CmdMsgByte cmdId, T arg, bool reqAc = false, CmdMsgByte ackCmdId = 1, unsigned int timeout = DEFAULT_TIMEOUT) { if (!startCommand) { @@ -203,7 +219,7 @@ class CmdMessenger * Note that the argument is sent in binary format */ template < class T > - bool sendBinCmd(byte cmdId, T arg, bool reqAc = false, byte ackCmdId = 1, + bool sendBinCmd(CmdMsgByte cmdId, T arg, bool reqAc = false, CmdMsgByte ackCmdId = 1, unsigned int timeout = DEFAULT_TIMEOUT) { if (!startCommand) { @@ -214,14 +230,14 @@ class CmdMessenger return false; } - bool sendCmd(byte cmdId); - bool sendCmd(byte cmdId, bool reqAc, byte ackCmdId); + bool sendCmd(CmdMsgByte cmdId); + bool sendCmd(CmdMsgByte cmdId, bool reqAc, CmdMsgByte ackCmdId); // **** Command sending with multiple arguments **** - void sendCmdStart(byte cmdId); + void sendCmdStart(CmdMsgByte cmdId); void sendCmdEscArg(char *arg); void sendCmdfArg(char *fmt, ...); - bool sendCmdEnd(bool reqAc = false, byte ackCmdId = 1, unsigned int timeout = DEFAULT_TIMEOUT); + bool sendCmdEnd(bool reqAc = false, CmdMsgByte ackCmdId = 1, unsigned int timeout = DEFAULT_TIMEOUT); /** * Send a single argument as string @@ -229,12 +245,38 @@ class CmdMessenger */ template < class T > void sendCmdArg(T arg) { - if (startCommand) { - comms->print(field_separator); - comms->print(arg); + if (startCommand) { +#if !defined(MBED) // Arduino and ReadBear OK + comms->print(field_separator); + comms->print(arg); +#else + comms->putc(field_separator); + comms->puts(arg); +#endif } + } +#if defined(MBED) + void sendCmdArg(bool arg) { + comms->putc(field_separator); + comms->printf("%i", arg); + } + void sendCmdArg(float arg) { + comms->putc(field_separator); + comms->printf("%f", arg); + } + void sendCmdArg(long arg) { + comms->putc(field_separator); + comms->printf("%i", arg); + } + void sendCmdArg(int arg) { + comms->putc(field_separator); + comms->printf("%i", arg); + } +#endif + +#if !defined(MBED_STREAM_H) /** * Send a single argument as string with custom accuracy * Note that this will only succeed if a sendCmdStart has been issued first @@ -246,6 +288,7 @@ class CmdMessenger comms->print(arg, n); } } +#endif /** * Send double argument in scientific format. @@ -253,7 +296,7 @@ class CmdMessenger */ void sendCmdSciArg(double arg, unsigned int n = 6); - +#if !defined(MBED_STREAM_H) /** * Send a single argument in binary format * Note that this will only succeed if a sendCmdStart has been issued first @@ -265,6 +308,7 @@ class CmdMessenger writeBin(arg); } } +#endif // **** Command receiving **** bool readBoolArg();