2020-04-27 16:01:25 +00:00
|
|
|
#include "RedirectablePrint.h"
|
2020-12-25 07:17:56 +00:00
|
|
|
#include "concurrency/OSThread.h"
|
2021-03-15 02:00:20 +00:00
|
|
|
#include "configuration.h"
|
2020-04-27 16:01:25 +00:00
|
|
|
#include <assert.h>
|
2020-12-25 07:17:56 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
2021-03-15 02:42:57 +00:00
|
|
|
#include "RTC.h"
|
2020-04-27 16:01:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A printer that doesn't go anywhere
|
|
|
|
*/
|
|
|
|
NoopPrint noopPrint;
|
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
void RedirectablePrint::setDestination(Print *_dest) {
|
|
|
|
assert(_dest);
|
|
|
|
dest = _dest;
|
2020-11-12 23:48:25 +00:00
|
|
|
}
|
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
size_t RedirectablePrint::write(uint8_t c) {
|
|
|
|
// Always send the characters to our segger JTAG debugger
|
2020-11-12 23:48:25 +00:00
|
|
|
#ifdef SEGGER_STDOUT_CH
|
2021-03-08 09:10:48 +00:00
|
|
|
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
2020-11-12 23:48:25 +00:00
|
|
|
#endif
|
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
dest->write(c);
|
|
|
|
return 1; // We always claim one was written, rather than trusting what the
|
|
|
|
// serial port said (which could be zero)
|
2020-12-25 07:17:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
|
|
|
{
|
2021-03-15 02:00:20 +00:00
|
|
|
va_list copy;
|
2021-03-15 02:42:57 +00:00
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
va_copy(copy, arg);
|
|
|
|
int len = vsnprintf(printBuf, printBufLen, format, copy);
|
|
|
|
va_end(copy);
|
|
|
|
if (len < 0) {
|
|
|
|
va_end(arg);
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
if (len >= printBufLen) {
|
|
|
|
delete[] printBuf;
|
|
|
|
printBufLen *= 2;
|
|
|
|
printBuf = new char[printBufLen];
|
|
|
|
len = vsnprintf(printBuf, printBufLen, format, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
len = Print::write(printBuf, len);
|
|
|
|
return len;
|
2020-12-25 07:17:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define SEC_PER_DAY 86400
|
|
|
|
#define SEC_PER_HOUR 3600
|
|
|
|
#define SEC_PER_MIN 60
|
|
|
|
|
|
|
|
size_t RedirectablePrint::logDebug(const char *format, ...)
|
|
|
|
{
|
|
|
|
size_t r = 0;
|
|
|
|
|
2021-03-09 08:45:40 +00:00
|
|
|
if (!inDebugPrint) {
|
|
|
|
inDebugPrint = true;
|
|
|
|
|
|
|
|
va_list arg;
|
|
|
|
va_start(arg, format);
|
|
|
|
|
|
|
|
// Cope with 0 len format strings, but look for new line terminator
|
|
|
|
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
|
|
|
|
|
|
|
|
// If we are the first message on a report, include the header
|
|
|
|
if (!isContinuationMessage) {
|
2021-03-15 02:42:57 +00:00
|
|
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
|
|
|
|
if (rtc_sec > 0) {
|
|
|
|
long hms =rtc_sec % SEC_PER_DAY;
|
2021-03-09 08:45:40 +00:00
|
|
|
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
|
|
|
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
|
|
|
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
|
|
|
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
|
|
|
|
|
|
|
// Tear apart hms into h:m:s
|
|
|
|
int hour = hms / SEC_PER_HOUR;
|
|
|
|
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
|
|
|
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
|
|
|
|
|
|
|
r += printf("%02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
|
|
|
} else
|
|
|
|
r += printf("??:??:?? %u ", millis() / 1000);
|
|
|
|
|
|
|
|
auto thread = concurrency::OSThread::currentThread;
|
|
|
|
if (thread) {
|
|
|
|
print("[");
|
|
|
|
// printf("%p ", thread);
|
|
|
|
// assert(thread->ThreadName.length());
|
|
|
|
print(thread->ThreadName);
|
|
|
|
print("] ");
|
|
|
|
}
|
2020-12-25 07:17:56 +00:00
|
|
|
}
|
|
|
|
|
2021-03-09 08:45:40 +00:00
|
|
|
r += vprintf(format, arg);
|
|
|
|
va_end(arg);
|
2020-12-25 07:17:56 +00:00
|
|
|
|
2021-03-09 08:45:40 +00:00
|
|
|
isContinuationMessage = !hasNewline;
|
|
|
|
inDebugPrint = false;
|
2020-12-25 07:17:56 +00:00
|
|
|
}
|
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
return r;
|
2020-04-27 16:01:25 +00:00
|
|
|
}
|