diff --git a/.gitignore b/.gitignore index 4b5a695..3adcee3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ Debug/ Release/ +!include/sta/debug/ +!src/debug/ + # Doxygen docs/html docs/latex diff --git a/include/sta/debug/debug.hpp b/include/sta/debug/debug.hpp index 7a09609..25d757f 100644 --- a/include/sta/debug/debug.hpp +++ b/include/sta/debug/debug.hpp @@ -15,34 +15,46 @@ namespace sta /** * @brief Debug print message. * - * @param ... See @ref sta::PrintableUART::print + * @param ... See @ref sta::Printable::print * * @ingroup sta_core_debug */ -# define STA_DEBUG_PRINT(...) sta::Debug->print(__VA_ARGS__) +# define STA_DEBUG_PRINT(...) sta::Debug->print(__VA_ARGS__) /** - * @brief Debug print message followed by new-line to UART. + * @brief Debug print message followed by new-line to the printable. * - * @param ... See @ref sta::PrintableUART::println + * @param ... See @ref sta::Printable::println * * @ingroup sta_core_debug */ -# define STA_DEBUG_PRINTLN(...) sta::Debug->println(__VA_ARGS__) +# define STA_DEBUG_PRINTLN(...) sta::Debug->println(__VA_ARGS__) /** * @brief Formatted debug printing with new-line. * - * @param fmt See @ref sta::PrintableUART::printf - * @param ... See @ref sta::PrintableUART::printf + * @param fmt See @ref sta::Printable::printf + * @param ... See @ref sta::Printable::printf + * + * @ingroup sta_core_debug */ -# define STA_DEBUG_PRINTF(fmt, ...) sta::Debug->printf(fmt, __VA_ARGS__) +# define STA_DEBUG_PRINTF(fmt, ...) sta::Debug->printf(fmt, __VA_ARGS__) + +/** + * @brief Read data via printable. + * + * @param ... See @ref sta::Printable::read + * + * @ingroup sta_core_debug + */ +# define STA_DEBUG_READ(buffer, length) sta::Debug->read(buffer, length) #else // !STA_DEBUGGING_ENABLED -# define STA_DEBUG_PRINT(...) ((void)0) -# define STA_DEBUG_PRINTLN(...) ((void)0) -# define STA_DEBUG_PRINTF(fmt, ...) ((void)0) +# define STA_DEBUG_PRINT(...) ((void)0) +# define STA_DEBUG_PRINTLN(...) ((void)0) +# define STA_DEBUG_PRINTF(fmt, ...) ((void)0) +# define STA_DEBUG_READ(buffer, length) ((void)0) #endif // STA_DEBUGGING_ENABLED diff --git a/include/sta/debug/printing/printable.hpp b/include/sta/debug/printing/printable.hpp index 531522f..d453702 100644 --- a/include/sta/debug/printing/printable.hpp +++ b/include/sta/debug/printing/printable.hpp @@ -40,62 +40,70 @@ namespace sta /** * @brief Print single character. * - * @param c Character to print + * @param c Character to print + * @param newline If true, send a \r\n to start a new line. */ - void print(char c); + void print(char c, bool newline = false); /** * @brief Print boolean value. * - * @param b Boolean value + * @param b Boolean value + * @param newline If true, send a \r\n to start a new line. */ - void print(bool b); + void print(bool b, bool newline = false); /** * @brief Print floating point value. * - * @param d Floating point value + * @param d Floating point value + * @param newline If true, send a \r\n to start a new line. */ - void print(double d); + void print(double d, bool newline = false); /** * @brief Print integer in selected base. * - * @param num 8-bit unsigned integer - * @param base Integer base + * @param num 8-bit unsigned integer + * @param base Integer base + * @param newline If true, send a \r\n to start a new line. */ - void print(uint8_t num, IntegerBase base = IntegerBase::DEC); + void print(uint8_t num, IntegerBase base = IntegerBase::DEC, bool newline = false); /** * @brief Print integer in selected base. * - * @param num 16-bit unsigned integer - * @param base Integer base + * @param num 16-bit unsigned integer + * @param base Integer base + * @param newline If true, send a \r\n to start a new line. */ - void print(uint16_t num, IntegerBase base = IntegerBase::DEC); + void print(uint16_t num, IntegerBase base = IntegerBase::DEC, bool newline = false); /** * @brief Print integer in selected base. * - * @param num 32-bit unsigned integer - * @param base Integer base + * @param num 32-bit unsigned integer + * @param base Integer base + * @param newline If true, send a \r\n to start a new line. */ - void print(uint32_t num, IntegerBase base = IntegerBase::DEC); + void print(uint32_t num, IntegerBase base = IntegerBase::DEC, bool newline = false); /** * @brief Print c-string. * - * @param str Null terminated string + * @param str Null terminated string + * @param newline If true, send a \r\n to start a new line. */ - void print(const char * str); + void print(const char * str, bool newline = false); /** * @brief Print string. * * @param str String buffer * @param length String length + * @param newline If true, send a \r\n to start a new line. */ - virtual void print(const char * str, size_t length) = 0; + virtual void print(const char * str, size_t length, bool newline = false) = 0; /** * @brief Print new-line. @@ -161,7 +169,38 @@ namespace sta * @param length String length */ void println(const char * str, size_t length); + public: + /** + * @brief Read bytes. + * + * @param buffer Byte buffer + * @param length Buffer length + */ + virtual void read(uint8_t * buffer, size_t length) = 0; + /** + * @brief Read string. + * + * @param str String buffer + * @param length String length + */ + void read(char * str, size_t length); + + /** + * @brief Read floats. + * + * @param buffer Float buffer + * @param length Buffer length + */ + void read(float * buffer, size_t length); + + /** + * @brief Read doubles. + * + * @param buffer Double buffer + * @param length Buffer length + */ + void read(double * buffer, size_t length); private: /** * @brief Print unsigned integer in selected base. @@ -170,32 +209,36 @@ namespace sta * @param base Integer base * @param fmt printf format string for base 10 * @param size Size of value in bytes + * @param newline If true, send a \r\n to start a new line. */ - void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size); + void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size, bool newline = false); /** * @brief Print unsigned integer in base 10. * * @param value Unsigned integer value * @param fmt printf format string + * @param newline If true, send a \r\n to start a new line. */ - void printDec(uintmax_t value, const char * fmt); + void printDec(uintmax_t value, const char * fmt, bool newline = false); /** * @brief Print unsigned integer in base 2. * * @param value Unsigned integer value * @param digits Number of digits to print + * @param newline If true, send a \r\n to start a new line. */ - void printBin(uintmax_t value, size_t digits); + void printBin(uintmax_t value, size_t digits, bool newline = false); /** * @brief Print unsigned integer in base 16. * * @param value Unsigned integer value * @param digits Number of digits to print + * @param newline If true, send a \r\n to start a new line. */ - void printHex(uintmax_t value, size_t digits); + void printHex(uintmax_t value, size_t digits, bool newline = false); }; } // namespace sta diff --git a/include/sta/debug/printing/printable_printf.hpp b/include/sta/debug/printing/printable_printf.hpp index a0de3cd..4f9f7e5 100644 --- a/include/sta/debug/printing/printable_printf.hpp +++ b/include/sta/debug/printing/printable_printf.hpp @@ -23,8 +23,17 @@ namespace sta * * @param str String buffer * @param length String length + * @param newline If true, send a \r\n to start a new line. */ - void print(const char * str, size_t length) override; + void print(const char * str, size_t length, bool newline = false) override; + + /** + * @brief Read bytes. + * + * @param buffer Byte buffer + * @param length Buffer length + */ + void read(uint8_t * buffer, size_t length) override; }; } // namespace sta diff --git a/include/sta/debug/printing/printable_uart.hpp b/include/sta/debug/printing/printable_uart.hpp index 93f92c5..e97de02 100644 --- a/include/sta/debug/printing/printable_uart.hpp +++ b/include/sta/debug/printing/printable_uart.hpp @@ -32,8 +32,17 @@ namespace sta * * @param str String buffer * @param length String length + * @param newline If true, send a \r\n to start a new line. */ - void print(const char * str, size_t length) override; + void print(const char * str, size_t length, bool newline = false) override; + + /** + * @brief Read bytes. + * + * @param buffer Byte buffer + * @param length Buffer length + */ + void read(uint8_t * str, size_t length) override; private: UART * intf_; diff --git a/include/sta/debug/profile.hpp b/include/sta/debug/profile.hpp index f256ac5..50100c5 100644 --- a/include/sta/debug/profile.hpp +++ b/include/sta/debug/profile.hpp @@ -5,8 +5,8 @@ * Author: Dario */ -#ifndef STA_DEBUGGING_PROFILING_HPP -#define STA_DEBUGGING_PROFILING_HPP +#ifndef STA_CORE_PROFILE_HPP +#define STA_CORE_PROFILE_HPP #include @@ -44,4 +44,4 @@ namespace sta #endif // // STA_PROFILING_ENABLED -#endif // STA_DEBUGGING_PROFILING_HPP +#endif // STA_CORE_PROFILE_HPP diff --git a/include/sta/debug/spatz.hpp b/include/sta/debug/spatz.hpp new file mode 100644 index 0000000..7b69f4c --- /dev/null +++ b/include/sta/debug/spatz.hpp @@ -0,0 +1,66 @@ +#ifndef STA_CORE_SPATZ_HPP +#define STA_CORE_SPATZ_HPP + +#include + +#include +#ifdef STA_SPATZ_ENABLED + +#include +#ifndef STA_DEBUGGING_ENABLED +# error "Cannot use SPATZ without debugging being enabled." +#endif // STA_DEBUGGING_ENABLED + +namespace sta +{ + namespace spatz + { + /** + * @brief Initialize SPATZ for in-the-loop testing. + * + * @param mutex A mutex used to make SPATZ thread-safe. + */ + void init(Mutex * mutex); + + /** + * @brief Request bytes for a specific sensor id via the printable. + * + * @param id The id of the sensor to request data for. + * @param buffer The byte buffer to write the data to. + * @param length The number of the bytes to request. + */ + void request(uint8_t id, uint8_t * buffer, size_t length); + + /** + * @brief Request floats for a specific sensor id via the printable. + * + * @param id The id of the sensor to request data for. + * @param buffer The float buffer to write the data to. + * @param length The number of floats to request. + */ + void request(uint8_t id, float * buffer, size_t length); + + /** + * @brief Request doubles for a specific sensor id via the printable. + * + * @param id The id of the sensor to request data for. + * @param buffer The double buffer to write the data to. + * @param length The number of doubles to request. + */ + void request(uint8_t id, double * buffer, size_t length); + } // namespace spatz +} // namespace sta + +#else + +namespace sta +{ + namespace spatz + { + void init(Mutex * mutex); + } // namespace spatz +} // namespace sta + +#endif // STA_SPATZ_ENABLED + +#endif // STA_CORE_SPATZ_HPP diff --git a/src/debug/printing/printable.cpp b/src/debug/printing/printable.cpp index a3206bb..42b0191 100644 --- a/src/debug/printing/printable.cpp +++ b/src/debug/printing/printable.cpp @@ -27,82 +27,76 @@ namespace sta println(str); } - void Printable::print(char c) + void Printable::print(char c, bool newline /* = false */) { - print(&c, 1); + print(&c, 1, newline); } - void Printable::print(bool b) + void Printable::print(bool b, bool newline /* = false */) { - print(b ? "true" : "false"); + print(b ? "true" : "false", newline); } - void Printable::print(double d) + void Printable::print(double d, bool newline /* = false */) { char buffer[64]; snprintf(buffer, sizeof(buffer), "%f", d); - print(buffer); + print(buffer, newline); } - void Printable::print(uint8_t num, IntegerBase base) + void Printable::print(uint8_t num, IntegerBase base, bool newline /* = false */) { - printBase(num, base, "%" PRIu8, sizeof(num)); + printBase(num, base, "%" PRIu8, sizeof(num), newline); } - void Printable::print(uint16_t num, IntegerBase base) + void Printable::print(uint16_t num, IntegerBase base, bool newline /* = false */) { - printBase(num, base, "%" PRIu16, sizeof(num)); + printBase(num, base, "%" PRIu16, sizeof(num), newline); } - void Printable::print(uint32_t num, IntegerBase base) + void Printable::print(uint32_t num, IntegerBase base, bool newline /* = false */) { - printBase(num, base, "%" PRIu32, sizeof(num)); + printBase(num, base, "%" PRIu32, sizeof(num), newline); } - void Printable::print(const char * str) + void Printable::print(const char * str, bool newline /* = false */) { - print(str, strlen(str)); + print(str, strlen(str), newline); } void Printable::println() { - print("\r\n", 2); + print("\r\n", 2, false); } void Printable::println(char c) { - print(&c, 1); - println(); + print(&c, 1, true); } void Printable::println(bool b) { - print(b); - println(); + print(b, true); } void Printable::println(double d) { - print(d); - println(); + print(d, true); } void Printable::println(uint8_t num, IntegerBase base) { - print(num, base); - println(); + print(num, base, true); } void Printable::println(uint16_t num, IntegerBase base) { - print(num, base); - println(); + print(num, base, true); } void Printable::println(uint32_t num, IntegerBase base) { - print(num, base); - println(); + print(num, base, true); } void Printable::println(const char * str) @@ -112,26 +106,25 @@ namespace sta void Printable::println(const char * str, size_t length) { - print(str, length); - println(); + print(str, length, true); } - void Printable::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size) + void Printable::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size, bool newline /* = false */) { switch (base) { case IntegerBase::DEC: - printDec(num, fmt); + printDec(num, fmt, newline); break; case IntegerBase::BIN: // Digits in base 2 = size in bytes * 8 - printBin(num, size * 8); + printBin(num, size * 8, newline); break; case IntegerBase::HEX: // Digits in base 16 = size in bytes * 2 - printHex(num, size * 2); + printHex(num, size * 2, newline); break; default: @@ -139,14 +132,14 @@ namespace sta } } - void Printable::printDec(uintmax_t num, const char * fmt) + void Printable::printDec(uintmax_t num, const char * fmt, bool newline /* = false */) { char buffer[64]; snprintf(buffer, sizeof(buffer), fmt, static_cast(num)); - print(buffer); + print(buffer, newline); } - void Printable::printBin(uintmax_t value, size_t digits) + void Printable::printBin(uintmax_t value, size_t digits, bool newline /* = false */) { // Need 8 digits for every byte char buffer[sizeof(value) * 8]; @@ -168,10 +161,10 @@ namespace sta buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1); } - print(buffer, digits); + print(buffer, digits, newline); } - void Printable::printHex(uintmax_t value, size_t digits) + void Printable::printHex(uintmax_t value, size_t digits, bool newline /* = false */) { // Need 2 digits for every byte char buffer[sizeof(value) * 2]; @@ -179,7 +172,7 @@ namespace sta // Check bounds if (digits > sizeof(buffer)) { - print(""); + print("", newline); return; } // Nothing to do @@ -197,7 +190,22 @@ namespace sta buffer[i] = '0' + hex; } - print(buffer, digits); + print(buffer, digits, newline); + } + + void Printable::read(char * str, size_t length) + { + read(reinterpret_cast(str), length * sizeof(char)); + } + + void Printable::read(float * buffer, size_t length) + { + read(reinterpret_cast(buffer), length * sizeof(float)); + } + + void Printable::read(double * buffer, size_t length) + { + read(reinterpret_cast(buffer), length * sizeof(double)); } } // namespace sta diff --git a/src/debug/printing/printable_printf.cpp b/src/debug/printing/printable_printf.cpp index 07357f5..900c5fc 100644 --- a/src/debug/printing/printable_printf.cpp +++ b/src/debug/printing/printable_printf.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -10,11 +11,22 @@ namespace sta } - void PrintablePrintf::print(const char * str, size_t length) + void PrintablePrintf::print(const char * str, size_t length, bool newline /* = false */) { STA_ASSERT(str != nullptr); STA_ASSERT(length > 0); printf("%.*s", length, str); + + if (newline) + printf("\r\n"); + } + + void PrintablePrintf::read(uint8_t * str, size_t length) + { + STA_ASSERT(str != nullptr); + STA_ASSERT(length > 0); + + STA_NOT_IMPLEMENTED(); } } // namespace sta diff --git a/src/debug/printing/printable_uart.cpp b/src/debug/printing/printable_uart.cpp index f3f7453..be750d7 100644 --- a/src/debug/printing/printable_uart.cpp +++ b/src/debug/printing/printable_uart.cpp @@ -17,11 +17,25 @@ namespace sta STA_ASSERT(intf->settings().mode == UARTMode::RX || intf->settings().mode == UARTMode::RX_TX); } - void PrintableUART::print(const char * str, size_t length) + void PrintableUART::print(const char * str, size_t length, bool newline /* = false */) { intf_->acquire(); intf_->transfer(reinterpret_cast(str), length); + + if (newline) + { + const char * linebreak = "\r\n"; + intf_->transfer(reinterpret_cast(linebreak), 2); + } + intf_->release(); } + void PrintableUART::read(uint8_t * buffer, size_t length) + { + intf_->acquire(); + intf_->receive(buffer, length); + intf_->release(); + } + } // namespace sta diff --git a/src/debug/spatz.cpp b/src/debug/spatz.cpp new file mode 100644 index 0000000..2f22c0b --- /dev/null +++ b/src/debug/spatz.cpp @@ -0,0 +1,71 @@ +#include + +#ifdef STA_SPATZ_ENABLED + +#ifndef STA_INIT_SPATZ_ID +# error "The ID used to communicate SPATZ initialization was not defined." +#endif // STA_INIT_SPATZ_ID + +namespace sta +{ + namespace spatz + { + sta::Mutex * mutex_; + + void init(sta::Mutex * mutex) + { + mutex_ = mutex; + uint8_t msg = 0xFF; + + sta::lock_guard lock(*mutex_); + + // Wait until SPATZ sends the init byte. + while (msg != STA_INIT_SPATZ_ID) + { + Debug->read(&msg, 1); + } + } + + void request(uint8_t id, uint8_t * buffer, size_t length) + { + sta::lock_guard lock(*mutex_); + + Debug->println("%d", id); + Debug->read(buffer, length); + } + + void request(uint8_t id, float * buffer, size_t length) + { + sta::lock_guard lock(*mutex_); + + // Debug->println(id, IntegerBase::DEC); + + Debug->printf("%d", id); + Debug->read(buffer, length); + } + + void request(uint8_t id, double * buffer, size_t length) + { + sta::lock_guard lock(*mutex_); + + Debug->println("%d", id); + Debug->read(buffer, length); + } + } // namespace spatz +} // namespace sta + +#else + +namespace sta +{ + namespace spatz + { + void init(sta::Mutex * mutex) + { + // Nothing to do here. + } + } // namespace spatz +} // namespace sta + + +#endif // STA_SPATZ_ENABLED