diff --git a/lib/log/GWLog.cpp b/lib/log/GWLog.cpp index 5c3aad6..c002fe9 100644 --- a/lib/log/GWLog.cpp +++ b/lib/log/GWLog.cpp @@ -1,25 +1,38 @@ #include "GwLog.h" -GwLog::GwLog(bool logSerial, int level){ - this->logSerial=logSerial; +class DefaultLogWriter: public GwLogWriter{ + public: + virtual ~DefaultLogWriter(){}; + virtual void write(const char *data){ + Serial.print(data); + } +}; + +GwLog::GwLog(int level, GwLogWriter *writer){ logLevel=level; + if (writer == NULL) writer=new DefaultLogWriter(); + this->writer=writer; } void GwLog::logString(const char *fmt,...){ + if (! writer) return; va_list args; va_start(args,fmt); vsnprintf(buffer,99,fmt,args); - if (logSerial){ - Serial.print("LOG: "); - Serial.println(buffer); - } + writer->write(prefix.c_str()); + writer->write(buffer); + writer->write("\n"); } void GwLog::logDebug(int level,const char *fmt,...){ if (level > logLevel) return; + if (! writer) return; va_list args; va_start(args,fmt); vsnprintf(buffer,99,fmt,args); - if (logSerial){ - Serial.print("LOG: "); - Serial.println(buffer); - } + writer->write(prefix.c_str()); + writer->write(buffer); + writer->write("\n"); +} +void GwLog::setWriter(GwLogWriter *writer){ + if (this->writer) delete this->writer; + this->writer=writer; } diff --git a/lib/log/GwLog.h b/lib/log/GwLog.h index 379ea5e..5a24858 100644 --- a/lib/log/GwLog.h +++ b/lib/log/GwLog.h @@ -1,17 +1,25 @@ #ifndef _GWLOG_H #define _GWLOG_H #include + +class GwLogWriter{ + public: + virtual ~GwLogWriter(){} + virtual void write(const char *data)=0; +}; class GwLog{ private: char buffer[100]; - bool logSerial=false; int logLevel=1; + GwLogWriter *writer; public: static const int LOG=1; static const int ERROR=0; static const int DEBUG=3; static const int TRACE=2; - GwLog(bool logSerial,int level=LOG); + String prefix="LOG:"; + GwLog(int level=LOG, GwLogWriter *writer=NULL); + void setWriter(GwLogWriter *writer); void logString(const char *fmt,...); void logDebug(int level, const char *fmt,...); int isActive(int level){return level <= logLevel;}; diff --git a/lib/serial/GwSerial.cpp b/lib/serial/GwSerial.cpp new file mode 100644 index 0000000..ef4b060 --- /dev/null +++ b/lib/serial/GwSerial.cpp @@ -0,0 +1,66 @@ +#include "GwSerial.h" +class SerialWriter : public GwBufferWriter{ + private: + uart_port_t num; + public: + SerialWriter(uart_port_t num){ + this->num=num; + } + virtual ~SerialWriter(){} + virtual int write(const uint8_t *buffer,size_t len){ + return uart_tx_chars(num,(const char *)buffer,len); + } + + +}; +GwSerial::GwSerial(GwLog *logger, uart_port_t num) +{ + this->logger = logger; + this->num = num; + this->buffer = new GwBuffer(logger); + this->writer = new SerialWriter(num); +} +GwSerial::~GwSerial() +{ + delete buffer; + delete writer; +} +int GwSerial::setup(int baud, int rxpin, int txpin) +{ + uart_config_t config = { + .baud_rate = baud, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + }; + if (uart_driver_install(num, bufferSize, 0, 0, NULL, 0) != ESP_OK) + { + return -1; + } + // Configure UART parameters + if (uart_param_config(num, &config) != ESP_OK) + { + return -2; + } + if (uart_set_pin(num, txpin, rxpin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE) != ESP_OK) + { + return -3; + } + buffer->reset(); + initialized = true; + return true; +} +bool GwSerial::isInitialized() { return initialized; } +size_t GwSerial::enqueue(const uint8_t *data, size_t len) +{ + return buffer->addData(data, len); +} +GwBuffer::WriteStatus GwSerial::write(){ + return buffer->fetchData(writer,false); +} +const char *GwSerial::read(){ + char buffer[10]; + uart_read_bytes(num,(uint8_t *)(&buffer),10,0); + return NULL; +} \ No newline at end of file diff --git a/lib/serial/GwSerial.h b/lib/serial/GwSerial.h new file mode 100644 index 0000000..1161f21 --- /dev/null +++ b/lib/serial/GwSerial.h @@ -0,0 +1,24 @@ +#ifndef _GWSERIAL_H +#define _GWSERIAL_H +#include "driver/uart.h" +#include "GwLog.h" +#include "GwBuffer.h" +class SerialWriter; +class GwSerial{ + private: + GwBuffer *buffer; + GwLog *logger; + SerialWriter *writer; + uart_port_t num; + bool initialized=false; + public: + static const int bufferSize=200; + GwSerial(GwLog *logger,uart_port_t num); + ~GwSerial(); + int setup(int baud,int rxpin,int txpin); + bool isInitialized(); + size_t enqueue(const uint8_t *data, size_t len); + GwBuffer::WriteStatus write(); + const char *read(); +}; +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index ad27fd6..b95cac5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,8 +15,6 @@ #define VERSION "0.1.0" #include "GwHardware.h" -#define LOG_SERIAL true - #include #include // This will automatically choose right CAN library and create suitable NMEA2000 object #include @@ -37,11 +35,12 @@ #include "GwSocketServer.h" #include "GwBoatData.h" #include "GwMessage.h" +#include "GwSerial.h" typedef std::map StringMap; -GwLog logger(LOG_SERIAL,GwLog::DEBUG); +GwLog logger(GwLog::DEBUG,NULL); GwConfigHandler config(&logger); GwWifi gwWifi(&config,&logger); GwSocketServer socketServer(&config,&logger); @@ -159,6 +158,15 @@ GwConfigInterface *sendTCP=NULL; GwConfigInterface *sendSeasmart=NULL; GwConfigInterface *systemName=NULL; +GwSerial usbSerial(&logger, UART_NUM_0); +class GwSerialLog : public GwLogWriter{ + public: + virtual ~GwSerialLog(){} + virtual void write(const char *data){ + usbSerial.enqueue((const uint8_t*)data,strlen(data)); //ignore any errors + } + +}; void setup() { uint8_t chipid[6]; @@ -170,9 +178,20 @@ void setup() { if (usbBaud){ baud=usbBaud->asInt(); } - Serial.begin(baud); - Serial.println("Starting..."); - Serial.println(config.toString()); + int st=usbSerial.setup(baud,3,1); //TODO: PIN defines + if (st < 0){ + //falling back to old style serial for logging + Serial.begin(baud); + Serial.printf("fallback serial enabled, error was %d\n",st); + logger.prefix="FALLBACK:"; + } + else{ + GwSerialLog *writer=new GwSerialLog(); + logger.prefix="GWSERIAL:"; + logger.setWriter(writer); + logger.logDebug(GwLog::LOG,"created GwSerial for USB port"); + } + logger.logDebug(GwLog::LOG,"config: %s", config.toString().c_str()); sendUsb=config.getConfigItem(config.sendUsb,true); sendTCP=config.getConfigItem(config.sendTCP,true); sendSeasmart=config.getConfigItem(config.sendSeasmart,true); @@ -290,7 +309,7 @@ void setup() { }); webserver.onNotFound(notFound); webserver.begin(); - Serial.println("HTTP server started"); + logger.logDebug(GwLog::LOG,"HTTP server started"); MDNS.addService("_http","_tcp",80); @@ -325,7 +344,7 @@ void setup() { NodeAddress = preferences.getInt("LastNodeAddress", 32); // Read stored last NodeAddress, default 32 preferences.end(); - Serial.printf("NodeAddress=%d\n", NodeAddress); + logger.logDebug(GwLog::LOG,"NodeAddress=%d\n", NodeAddress); NMEA2000.SetMode(tNMEA2000::N2km_ListenAndNode, NodeAddress); @@ -369,7 +388,14 @@ void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg) { socketServer.sendToClients(buf); } if (sendUsb->asBoolean()){ - Serial.println(buf); + int len=strlen(buf); + if (len >= (MAX_NMEA0183_MESSAGE_SIZE -2)) return; + buf[len]=0x0d; + len++; + buf[len]=0x0a; + len++; + buf[len]=0; + usbSerial.enqueue((const uint8_t*)buf,len); } } @@ -396,10 +422,9 @@ void loop() { msg->process(); msg->unref(); } - - // Dummy to empty input buffer to avoid board to stuck with e.g. NMEA Reader - if ( Serial.available() ) { - Serial.read(); + if (usbSerial.write() == GwBuffer::ERROR){ + logger.logDebug(GwLog::DEBUG,"overflow in USB serial"); } + usbSerial.read(); }