From 4a155b192204598c0141a859c268995039d672a4 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 20 Oct 2024 14:22:23 +0100 Subject: [PATCH] [Utils] Move generally useful methods to utils --- src/BuildOpt.h | 10 +- src/Module.cpp | 96 +--------------- src/Module.h | 24 +--- src/modules/LR11x0/LR11x0.cpp | 4 +- src/protocols/AX25/AX25.cpp | 4 +- src/protocols/Pager/Pager.cpp | 12 +- src/protocols/PhysicalLayer/PhysicalLayer.cpp | 3 +- src/utils/CRC.cpp | 4 +- src/utils/FEC.h | 10 -- src/utils/Utils.cpp | 105 ++++++++++++++++++ src/utils/Utils.h | 42 +++++++ 11 files changed, 170 insertions(+), 144 deletions(-) create mode 100644 src/utils/Utils.cpp create mode 100644 src/utils/Utils.h diff --git a/src/BuildOpt.h b/src/BuildOpt.h index 60859443a..3df71d83c 100644 --- a/src/BuildOpt.h +++ b/src/BuildOpt.h @@ -473,10 +473,10 @@ #if RADIOLIB_DEBUG #if defined(RADIOLIB_BUILD_ARDUINO) - #define RADIOLIB_DEBUG_PRINT(...) Module::serialPrintf(__VA_ARGS__) - #define RADIOLIB_DEBUG_PRINTLN(M, ...) Module::serialPrintf(M "\n", ##__VA_ARGS__) - #define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) Module::serialPrintf(LEVEL "" M, ##__VA_ARGS__) - #define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) Module::serialPrintf(LEVEL "" M "\n", ##__VA_ARGS__) + #define RADIOLIB_DEBUG_PRINT(...) rlb_printf(__VA_ARGS__) + #define RADIOLIB_DEBUG_PRINTLN(M, ...) rlb_printf(M "\n", ##__VA_ARGS__) + #define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) rlb_printf(LEVEL "" M, ##__VA_ARGS__) + #define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) rlb_printf(LEVEL "" M "\n", ##__VA_ARGS__) // some platforms do not support printf("%f"), so it has to be done this way #define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL); RADIOLIB_DEBUG_PORT.print(VAL, DECIMALS) @@ -492,7 +492,7 @@ #define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL "%.3f", VAL) #endif - #define RADIOLIB_DEBUG_HEXDUMP(LEVEL, ...) Module::hexdump(LEVEL, __VA_ARGS__) + #define RADIOLIB_DEBUG_HEXDUMP(LEVEL, ...) rlb_hexdump(LEVEL, __VA_ARGS__) #else #define RADIOLIB_DEBUG_PRINT(...) {} #define RADIOLIB_DEBUG_PRINTLN(...) {} diff --git a/src/Module.cpp b/src/Module.cpp index 30d38b035..33d9c09b4 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -1,15 +1,9 @@ #include "Module.h" // the following is probably only needed on non-Arduino builds -#include #include #include -#if RADIOLIB_DEBUG -// needed for debug print -#include -#endif - #if defined(RADIOLIB_BUILD_ARDUINO) #include "ArduinoHal.h" @@ -461,69 +455,7 @@ void Module::waitForMicroseconds(RadioLibTime_t start, RadioLibTime_t len) { #endif } -uint32_t Module::reflect(uint32_t in, uint8_t bits) { - uint32_t res = 0; - for(uint8_t i = 0; i < bits; i++) { - res |= (((in & ((uint32_t)1 << i)) >> i) << (bits - i - 1)); - } - return(res); -} - #if RADIOLIB_DEBUG -void Module::hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset, uint8_t width, bool be) { - size_t rem_len = len; - for(size_t i = 0; i < len; i+=16) { - char str[120]; - sprintf(str, "%08" PRIx32 ": ", (uint32_t)i+offset); - size_t line_len = 16; - if(rem_len < line_len) { - line_len = rem_len; - } - for(size_t j = 0; j < line_len; j+=width) { - if(width > 1) { - int m = 0; - int step = width/2; - if(be) { - step *= -1; - } - for(int32_t k = width - 1; k >= -width + 1; k+=step) { - sprintf(&str[10 + (j+m)*3], "%02x ", data[i+j+k+m]); - m++; - } - } else { - sprintf(&str[10 + (j)*3], "%02x ", data[i+j]); - } - } - for(size_t j = line_len; j < 16; j++) { - sprintf(&str[10 + j*3], " "); - } - //str[56] = '|'; - str[58] = ' '; - - // at this point we need to start escaping "%" characters - char* strPtr = &str[59]; - for(size_t j = 0; j < line_len; j++) { - char c = data[i+j]; - if((c < ' ') || (c > '~')) { - c = '.'; - } else if(c == '%') { - *strPtr++ = '%'; - } - sprintf(strPtr++, "%c", c); - - } - for(size_t j = line_len; j < 16; j++) { - sprintf(strPtr++, " "); - } - if(level) { - RADIOLIB_DEBUG_PRINT(level); - } - RADIOLIB_DEBUG_PRINT(str); - RADIOLIB_DEBUG_PRINTLN(); - rem_len -= 16; - } -} - void Module::regdump(const char* level, uint16_t start, size_t len) { #if RADIOLIB_STATIC_ONLY uint8_t buff[RADIOLIB_STATIC_ARRAY_SIZE]; @@ -531,39 +463,13 @@ void Module::regdump(const char* level, uint16_t start, size_t len) { uint8_t* buff = new uint8_t[len]; #endif SPIreadRegisterBurst(start, len, buff); - hexdump(level, buff, len, start); + rlb_hexdump(level, buff, len, start); #if !RADIOLIB_STATIC_ONLY delete[] buff; #endif } #endif -#if RADIOLIB_DEBUG && defined(RADIOLIB_BUILD_ARDUINO) -// https://github.com/esp8266/Arduino/blob/65579d29081cb8501e4d7f786747bf12e7b37da2/cores/esp8266/Print.cpp#L50 -size_t Module::serialPrintf(const char* format, ...) { - va_list arg; - va_start(arg, format); - char temp[64]; - char* buffer = temp; - size_t len = vsnprintf(temp, sizeof(temp), format, arg); - va_end(arg); - if (len > sizeof(temp) - 1) { - buffer = new char[len + 1]; - if (!buffer) { - return 0; - } - va_start(arg, format); - vsnprintf(buffer, len + 1, format, arg); - va_end(arg); - } - len = RADIOLIB_DEBUG_PORT.write(reinterpret_cast(buffer), len); - if (buffer != temp) { - delete[] buffer; - } - return len; -} -#endif - void Module::setRfSwitchPins(uint32_t rxEn, uint32_t txEn) { // This can be on the stack, setRfSwitchTable copies the contents const uint32_t pins[] = { diff --git a/src/Module.h b/src/Module.h index e6e4acafe..5d5072bf5 100644 --- a/src/Module.h +++ b/src/Module.h @@ -3,6 +3,7 @@ #include "TypeDef.h" #include "Hal.h" +#include "utils/Utils.h" #if defined(RADIOLIB_BUILD_ARDUINO) #include @@ -505,26 +506,7 @@ class Module { */ void waitForMicroseconds(RadioLibTime_t start, RadioLibTime_t len); - /*! - \brief Function to reflect bits within a byte. - \param in The input to reflect. - \param bits Number of bits to reflect. - \return The reflected input. - */ - static uint32_t reflect(uint32_t in, uint8_t bits); - #if RADIOLIB_DEBUG - /*! - \brief Function to dump data as hex into the debug port. - \param level RadioLib debug level, set to NULL to not print. - \param data Data to dump. - \param len Number of bytes to dump. - \param offset Address offset to add when printing the data. - \param width Word width (1 for uint8_t, 2 for uint16_t, 4 for uint32_t). - \param be Print multi-byte data as big endian. Defaults to false. - */ - static void hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset = 0, uint8_t width = 1, bool be = false); - /*! \brief Function to dump device registers as hex into the debug port. \param level RadioLib debug level, set to NULL to not print. @@ -534,10 +516,6 @@ class Module { void regdump(const char* level, uint16_t start, size_t len); #endif - #if RADIOLIB_DEBUG and defined(RADIOLIB_BUILD_ARDUINO) - static size_t serialPrintf(const char* format, ...); - #endif - #if !RADIOLIB_GODMODE private: #endif diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index ee2e4b1c3..1736f8c95 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -1779,7 +1779,7 @@ int16_t LR11x0::isGnssScanCapable() { size_t len = sz > 32 ? 32 : sz/sizeof(uint32_t); state = this->readRegMem32(addr, buff, len); RADIOLIB_ASSERT(state); - Module::hexdump(NULL, (uint8_t*)buff, len*sizeof(uint32_t), addr); + RADIOLIB_DEBUG_HEXDUMP(NULL, (uint8_t*)buff, len*sizeof(uint32_t), addr); addr += len*sizeof(uint32_t); sz -= len*sizeof(uint32_t); } @@ -1789,7 +1789,7 @@ int16_t LR11x0::isGnssScanCapable() { RADIOLIB_DEBUG_BASIC_PRINTLN("Almanac[%d]:", i); state = this->gnssAlmanacReadSV(i, almanac); RADIOLIB_ASSERT(state); - Module::hexdump(NULL, almanac, 22); + RADIOLIB_DEBUG_HEXDUMP(NULL, almanac, 22); } #endif diff --git a/src/protocols/AX25/AX25.cpp b/src/protocols/AX25/AX25.cpp index 82a64cebc..22e1220a2 100644 --- a/src/protocols/AX25/AX25.cpp +++ b/src/protocols/AX25/AX25.cpp @@ -1,5 +1,7 @@ #include "AX25.h" + #include + #if !RADIOLIB_EXCLUDE_AX25 AX25Frame::AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control) @@ -369,7 +371,7 @@ int16_t AX25Client::sendFrame(AX25Frame* frame) { // flip bit order for(size_t i = 0; i < frameBuffLen; i++) { - frameBuff[i] = Module::reflect(frameBuff[i], 8); + frameBuff[i] = rlb_reflect(frameBuff[i], 8); } // calculate diff --git a/src/protocols/Pager/Pager.cpp b/src/protocols/Pager/Pager.cpp index e9aa14a47..e4914dd6b 100644 --- a/src/protocols/Pager/Pager.cpp +++ b/src/protocols/Pager/Pager.cpp @@ -1,6 +1,8 @@ #include "Pager.h" + #include #include + #if defined(ESP_PLATFORM) #include "esp_attr.h" #endif @@ -177,7 +179,7 @@ int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t // first insert the remainder from previous code word (if any) if(remBits > 0) { // this doesn't apply to BCD messages, so no need to check that here - uint8_t prev = Module::reflect(data[dataPos - 1], 8); + uint8_t prev = rlb_reflect(data[dataPos - 1], 8); prev >>= 1; msg[blockPos] |= (uint32_t)prev << (RADIOLIB_PAGER_CODE_WORD_LEN - 1 - remBits); } @@ -191,7 +193,7 @@ int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t if(encoding == RADIOLIB_PAGER_BCD) { symbol = encodeBCD(symbol); } - symbol = Module::reflect(symbol, 8); + symbol = rlb_reflect(symbol, 8); symbol >>= (8 - symbolLength); // insert the next message symbol @@ -205,7 +207,7 @@ int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t uint8_t numSteps = (symbolPos - RADIOLIB_PAGER_FUNC_BITS_POS + symbolLength)/symbolLength; for(uint8_t j = 0; j < numSteps; j++) { symbol = encodeBCD(' '); - symbol = Module::reflect(symbol, 8); + symbol = rlb_reflect(symbol, 8); symbol >>= (8 - symbolLength); msg[blockPos] |= (uint32_t)symbol << symbolPos; symbolPos -= symbolLength; @@ -428,7 +430,7 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) { uint32_t symbol = prevSymbol << (symbolLength - ovfBits) | currSymbol; // finally, we can flip the bits - symbol = Module::reflect((uint8_t)symbol, 8); + symbol = rlb_reflect((uint8_t)symbol, 8); symbol >>= (8 - symbolLength); // decode BCD and we're done @@ -446,7 +448,7 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) { while(bitPos >= RADIOLIB_PAGER_MESSAGE_END_POS) { // get the message symbol from the code word and reverse bits uint32_t symbol = (cw & (0x7FUL << bitPos)) >> bitPos; - symbol = Module::reflect((uint8_t)symbol, 8); + symbol = rlb_reflect((uint8_t)symbol, 8); symbol >>= (8 - symbolLength); // decode BCD if needed diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index 5176073c9..82eb5fba9 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -1,4 +1,5 @@ #include "PhysicalLayer.h" + #include PhysicalLayer::PhysicalLayer(float step, size_t maxLen) { @@ -481,7 +482,7 @@ void PhysicalLayer::updateDirectBuffer(uint8_t bit) { // check complete byte if(this->bufferBitPos == 8) { - this->buffer[this->bufferWritePos] = Module::reflect(this->buffer[this->bufferWritePos], 8); + this->buffer[this->bufferWritePos] = rlb_reflect(this->buffer[this->bufferWritePos], 8); RADIOLIB_DEBUG_PROTOCOL_PRINTLN("R\t%X", this->buffer[this->bufferWritePos]); this->bufferWritePos++; diff --git a/src/utils/CRC.cpp b/src/utils/CRC.cpp index ac7fb74f0..d0dd03a0a 100644 --- a/src/utils/CRC.cpp +++ b/src/utils/CRC.cpp @@ -11,7 +11,7 @@ uint32_t RadioLibCRC::checksum(const uint8_t* buff, size_t len) { if(i % 8 == 0) { uint32_t in = buff[pos++]; if(this->refIn) { - in = Module::reflect(in, 8); + in = rlb_reflect(in, 8); } crc ^= (in << (this->size - 8)); } @@ -26,7 +26,7 @@ uint32_t RadioLibCRC::checksum(const uint8_t* buff, size_t len) { crc ^= this->out; if(this->refOut) { - crc = Module::reflect(crc, this->size); + crc = rlb_reflect(crc, this->size); } crc &= (uint32_t)0xFFFFFFFF >> (32 - this->size); return(crc); diff --git a/src/utils/FEC.h b/src/utils/FEC.h index 807120c81..9b9e99c37 100644 --- a/src/utils/FEC.h +++ b/src/utils/FEC.h @@ -71,16 +71,6 @@ class RadioLibBCH { // the global singleton extern RadioLibBCH RadioLibBCHInstance; -// macros to access bits in byte array, from http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html -#define SET_BIT_IN_ARRAY_MSB(A, k) ( A[((k)/8)] |= (1 << ((k)%8)) ) -#define CLEAR_BIT_IN_ARRAY_MSB(A, k) ( A[((k)/8)] &= ~(1 << ((k)%8)) ) -#define TEST_BIT_IN_ARRAY_MSB(A, k) ( A[((k)/8)] & (1 << ((k)%8)) ) -#define GET_BIT_IN_ARRAY_MSB(A, k) ( (A[((k)/8)] & (1 << ((k)%8))) ? 1 : 0 ) -#define SET_BIT_IN_ARRAY_LSB(A, k) ( A[((k)/8)] |= (1 << (7 - ((k)%8))) ) -#define CLEAR_BIT_IN_ARRAY_LSB(A, k) ( A[((k)/8)] &= ~(1 << (7 - ((k)%8))) ) -#define TEST_BIT_IN_ARRAY_LSB(A, k) ( A[((k)/8)] & (1 << (7 - ((k)%8))) ) -#define GET_BIT_IN_ARRAY_LSB(A, k) ( (A[((k)/8)] & (1 << (7 - ((k)%8)))) ? 1 : 0 ) - /*! \class RadioLibConvCode \brief Class to perform convolutional coding with variable rates. diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp new file mode 100644 index 000000000..c2f12a6a1 --- /dev/null +++ b/src/utils/Utils.cpp @@ -0,0 +1,105 @@ +#include "Utils.h" + +#include +#include +#include +#include + +uint32_t rlb_reflect(uint32_t in, uint8_t bits) { + uint32_t res = 0; + for(uint8_t i = 0; i < bits; i++) { + res |= (((in & ((uint32_t)1 << i)) >> i) << (bits - i - 1)); + } + return(res); +} + +void rlb_hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset, uint8_t width, bool be) { + #if RADIOLIB_DEBUG + size_t rem_len = len; + for(size_t i = 0; i < len; i+=16) { + char str[120]; + sprintf(str, "%08" PRIx32 ": ", (uint32_t)i+offset); + size_t line_len = 16; + if(rem_len < line_len) { + line_len = rem_len; + } + for(size_t j = 0; j < line_len; j+=width) { + if(width > 1) { + int m = 0; + int step = width/2; + if(be) { + step *= -1; + } + for(int32_t k = width - 1; k >= -width + 1; k+=step) { + sprintf(&str[10 + (j+m)*3], "%02x ", data[i+j+k+m]); + m++; + } + } else { + sprintf(&str[10 + (j)*3], "%02x ", data[i+j]); + } + } + for(size_t j = line_len; j < 16; j++) { + sprintf(&str[10 + j*3], " "); + } + str[58] = ' '; + + // at this point we need to start escaping "%" characters + char* strPtr = &str[59]; + for(size_t j = 0; j < line_len; j++) { + char c = data[i+j]; + if((c < ' ') || (c > '~')) { + c = '.'; + } else if(c == '%') { + *strPtr++ = '%'; + } + sprintf(strPtr++, "%c", c); + + } + for(size_t j = line_len; j < 16; j++) { + sprintf(strPtr++, " "); + } + if(level) { + RADIOLIB_DEBUG_PRINT(level); + } + RADIOLIB_DEBUG_PRINT(str); + RADIOLIB_DEBUG_PRINTLN(); + rem_len -= 16; + } + + #else + // outside of debug, this does nothing + (void)level; + (void)data; + (void)len; + (void)offset; + (void)width; + (void)be; + + #endif +} + +#if RADIOLIB_DEBUG && defined(RADIOLIB_BUILD_ARDUINO) +// https://github.com/esp8266/Arduino/blob/65579d29081cb8501e4d7f786747bf12e7b37da2/cores/esp8266/Print.cpp#L50 +size_t rlb_printf(const char* format, ...) { + va_list arg; + va_start(arg, format); + char temp[64]; + char* buffer = temp; + size_t len = vsnprintf(temp, sizeof(temp), format, arg); + va_end(arg); + if (len > sizeof(temp) - 1) { + buffer = new char[len + 1]; + if (!buffer) { + return 0; + } + va_start(arg, format); + vsnprintf(buffer, len + 1, format, arg); + va_end(arg); + } + len = RADIOLIB_DEBUG_PORT.write(reinterpret_cast(buffer), len); + if (buffer != temp) { + delete[] buffer; + } + return len; +} +#endif diff --git a/src/utils/Utils.h b/src/utils/Utils.h new file mode 100644 index 000000000..44e4c776b --- /dev/null +++ b/src/utils/Utils.h @@ -0,0 +1,42 @@ +#if !defined(_RADIOLIB_UTILS_H) +#define _RADIOLIB_UTILS_H + +#include "TypeDef.h" + +#include +#include + +// macros to access bits in byte array, from http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html +#define SET_BIT_IN_ARRAY_MSB(A, k) ( A[((k)/8)] |= (1 << ((k)%8)) ) +#define CLEAR_BIT_IN_ARRAY_MSB(A, k) ( A[((k)/8)] &= ~(1 << ((k)%8)) ) +#define TEST_BIT_IN_ARRAY_MSB(A, k) ( A[((k)/8)] & (1 << ((k)%8)) ) +#define GET_BIT_IN_ARRAY_MSB(A, k) ( (A[((k)/8)] & (1 << ((k)%8))) ? 1 : 0 ) +#define SET_BIT_IN_ARRAY_LSB(A, k) ( A[((k)/8)] |= (1 << (7 - ((k)%8))) ) +#define CLEAR_BIT_IN_ARRAY_LSB(A, k) ( A[((k)/8)] &= ~(1 << (7 - ((k)%8))) ) +#define TEST_BIT_IN_ARRAY_LSB(A, k) ( A[((k)/8)] & (1 << (7 - ((k)%8))) ) +#define GET_BIT_IN_ARRAY_LSB(A, k) ( (A[((k)/8)] & (1 << (7 - ((k)%8)))) ? 1 : 0 ) + +/*! + \brief Function to reflect bits within a byte. + \param in The input to reflect. + \param bits Number of bits to reflect. + \return The reflected input. +*/ +uint32_t rlb_reflect(uint32_t in, uint8_t bits); + +/*! + \brief Function to dump data as hex into the debug port. + \param level RadioLib debug level, set to NULL to not print. + \param data Data to dump. + \param len Number of bytes to dump. + \param offset Address offset to add when printing the data. + \param width Word width (1 for uint8_t, 2 for uint16_t, 4 for uint32_t). + \param be Print multi-byte data as big endian. Defaults to false. +*/ +void rlb_hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset = 0, uint8_t width = 1, bool be = false); + +#if RADIOLIB_DEBUG and defined(RADIOLIB_BUILD_ARDUINO) +size_t rlb_printf(const char* format, ...); +#endif + +#endif