//----------------------------------------------------------------------------- // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778 // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ //----------------------------------------------------------------------------- #ifndef __DBG_H__ #define __DBG_H__ #if defined(F) && defined(ESP32) #undef F #define F(sl) (sl) #endif #include //----------------------------------------------------------------------------- // available levels #define DBG_ERROR 1 #define DBG_WARN 2 #define DBG_INFO 3 #define DBG_DEBUG 4 #define DBG_VERBOSE 5 //#define LOG_MAX_MSG_LEN 100 //----------------------------------------------------------------------------- // globally used level #ifndef DEBUG_LEVEL #define DEBUG_LEVEL DBG_INFO #endif #ifdef ARDUINO #include "Arduino.h" #endif #ifdef NDEBUG #define DBGPRINT(str) #define DBGPRINTLN(str) #else #ifdef ARDUINO #define DBG_CB std::function extern DBG_CB mCb; inline void registerDebugCb(DBG_CB cb) { mCb = cb; } #ifndef DSERIAL #define DSERIAL Serial #endif //template inline void DBGPRINT(String str) { DSERIAL.print(str); if(NULL != mCb) mCb(str); } //template inline void DBGPRINTLN(String str) { DBGPRINT(str); DBGPRINT(F("\r\n")); } inline void DHEX(uint8_t b) { if( b<0x10 ) DSERIAL.print(F("0")); DSERIAL.print(b,HEX); if(NULL != mCb) { if( b<0x10 ) mCb(F("0")); mCb(String(b, HEX)); } } /*inline void DHEX(uint16_t b) { if( b<0x10 ) DSERIAL.print(F("000")); else if( b<0x100 ) DSERIAL.print(F("00")); else if( b<0x1000 ) DSERIAL.print(F("0")); DSERIAL.print(b, HEX); if(NULL != mCb) { if( b<0x10 ) mCb(F("000")); else if( b<0x100 ) mCb(F("00")); else if( b<0x1000 ) mCb(F("0")); mCb(String(b, HEX)); } } inline void DHEX(uint32_t b) { if( b<0x10 ) DSERIAL.print(F("0000000")); else if( b<0x100 ) DSERIAL.print(F("000000")); else if( b<0x1000 ) DSERIAL.print(F("00000")); else if( b<0x10000 ) DSERIAL.print(F("0000")); else if( b<0x100000 ) DSERIAL.print(F("000")); else if( b<0x1000000 ) DSERIAL.print(F("00")); else if( b<0x10000000 ) DSERIAL.print(F("0")); DSERIAL.print(b, HEX); if(NULL != mCb) { if( b<0x10 ) mCb(F("0000000")); else if( b<0x100 ) mCb(F("000000")); else if( b<0x1000 ) mCb(F("00000")); else if( b<0x10000 ) mCb(F("0000")); else if( b<0x100000 ) mCb(F("000")); else if( b<0x1000000 ) mCb(F("00")); else if( b<0x10000000 ) mCb(F("0")); mCb(String(b, HEX)); } }*/ #endif #endif #if DEBUG_LEVEL >= DBG_ERROR #define PERR(str) DBGPRINT(F("E: ")); DBGPRINT(str); #define PERRLN(str) DBGPRINT(F("E: ")); DBGPRINTLN(str); #else #define PERR(str) #define PERRLN(str) #endif #if DEBUG_LEVEL >= DBG_WARN #define PWARN(str) DBGPRINT(F("W: ")); DBGPRINT(str); #define PWARNLN(str) DBGPRINT(F("W: ")); DBGPRINTLN(str); #else #define PWARN(str) #define PWARNLN(str) #endif #if DEBUG_LEVEL >= DBG_INFO #define PINFO(str) DBGPRINT(F("I: ")); DBGPRINT(str); #define PINFOLN(str) DBGPRINT(F("I: ")); DBGPRINTLN(str); #else #define PINFO(str) #define PINFOLN(str) #endif #if DEBUG_LEVEL >= DBG_DEBUG #define PDBG(str) DBGPRINT(F("D: ")); DBGPRINT(str); #define PDBGLN(str) DBGPRINT(F("D: ")); DBGPRINTLN(str); #else #define PDBG(str) #define PDBGLN(str) #endif #if DEBUG_LEVEL >= DBG_VERBOSE #define PVERB(str) DBGPRINT(F("V: ")); DBGPRINT(str); #define PVERBLN(str) DBGPRINT(F("V: ")); DBGPRINTLN(str); #else #define PVERB(str) #define PVERBLN(str) #endif #define DPRINT(level, str) ({\ switch(level) {\ case DBG_ERROR: PERR(str); break; \ case DBG_WARN: PWARN(str); break; \ case DBG_INFO: PINFO(str); break; \ case DBG_DEBUG: PDBG(str); break; \ default: PVERB(str); break; \ }\ }) #define DPRINTHEAD(level, id) ({\ DPRINT(level, F("(#")); DBGPRINT(String(id)); DBGPRINT(F(") "));\ }) #define DPRINTLN(level, str) ({\ switch(level) {\ case DBG_ERROR: PERRLN(str); break; \ case DBG_WARN: PWARNLN(str); break; \ case DBG_INFO: PINFOLN(str); break; \ case DBG_DEBUG: PDBGLN(str); break; \ default: PVERBLN(str); break; \ }\ }) // available text variables #define TXT_NOPYLD 1 #define TXT_INVSERNO 2 #define TXT_GDEVINF 3 #define TXT_DEVCTRL 4 #define TXT_INCRALM 5 #define DBGPRINT_TXT(text) ({\ switch(text) {\ case TXT_NOPYLD: DBGPRINT(F("no Payload received! (retransmits: ")); break; \ case TXT_INVSERNO: DBGPRINT(F("Requesting Inv SN ")); break; \ case TXT_GDEVINF: DBGPRINT(F("prepareDevInformCmd 0x")); break; \ case TXT_DEVCTRL: DBGPRINT(F("Devcontrol request 0x")); break; \ case TXT_INCRALM: DBGPRINT(F("alarm ID incremented to ")); break; \ default: ; break; \ }\ }) // available text variables w. lf #define TXT_TIMEOUT 1 #define TXT_NOPYLD2 2 #define DBGPRINTLN_TXT(text) ({\ switch(text) {\ case TXT_TIMEOUT: DBGPRINT(F("enqueued cmd failed/timeout\r\n")); break; \ case TXT_NOPYLD2: DBGPRINT(F("nothing received\r\n")); break; \ default: ; break; \ }\ }) /*class ahoyLog { public: ahoyLog() {} inline void logMsg(uint8_t lvl, bool newLine, const char *fmt, va_list args) { snprintf(mLogBuf, LOG_MAX_MSG_LEN, fmt, args); DSERIAL.print(mLogBuf); if(NULL != mCb) mCb(mLogBuf); if(newLine) { DSERIAL.print(F("\r\n")); if(NULL != mCb) mCb(F("\r\n")); } } inline void logError(const char *fmt, ...) { #if DEBUG_LEVEL >= DBG_ERROR va_list args; va_start(args, fmt); logMsg(DBG_ERROR, true, fmt, args); va_end(args); #endif } inline void logWarn(const char *fmt, ...) { #if DEBUG_LEVEL >= DBG_WARN va_list args; va_start(args, fmt); logMsg(DBG_ERROR, true, fmt, args); va_end(args); #endif } inline void logInfo(const char *fmt, ...) { #if DEBUG_LEVEL >= DBG_INFO va_list args; va_start(args, fmt); logMsg(DBG_ERROR, true, fmt, args); va_end(args); #endif } private: char mLogBuf[LOG_MAX_MSG_LEN]; DBG_CB mCb = NULL; };*/ #endif /*__DBG_H__*/