diff --git a/inc/f4ll/console_handler.h b/inc/f4ll/console_handler.h index 14e15a6..df3d265 100644 --- a/inc/f4ll/console_handler.h +++ b/inc/f4ll/console_handler.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -15,7 +16,7 @@ namespace f4ll { -class console_handler : public usart_core, public initialized_singleton +class console_handler : public initialized_singleton, public usart_core, public ioutput_stream { friend class initialized_singleton; @@ -41,7 +42,7 @@ private: void setup_receive(void); - // LL_UsartCore pure virtual function implementations + // usart_core pure virtual function implementations void receiver_idle(void) override; void transmission_complete(void) override; void framing_error(void) override; @@ -53,6 +54,24 @@ private: void tx_dma_half_transfer(void) override; void tx_dma_error(dma_helper::dma_error_type reason) override; + // ioutput_stream interface implementations + ioutput_stream &operator<<(ioutput_stream::format fmt) override; + ioutput_stream &operator<<(char const *str) override; + ioutput_stream &operator<<(char chr) override; + ioutput_stream &operator<<(uint8_t byte) override; + ioutput_stream &operator<<(uint16_t ui16) override; + ioutput_stream &operator<<(int16_t i16) override; + ioutput_stream &operator<<(uint32_t ui32) override; + ioutput_stream &operator<<(int32_t i32) override; + + // iotput_stream-related member variables + ioutput_stream::format m_fmt = ioutput_stream::format::dec; + + // iotput_stream-related helper functions + template void print_unsigned(T input); + template void print_signed(T input); + + // ringbuffer_ext m_tx_buffer; size_type m_bytes_sent = 0; diff --git a/inc/f4ll/output_stream.h b/inc/f4ll/output_stream.h new file mode 100644 index 0000000..7440f8a --- /dev/null +++ b/inc/f4ll/output_stream.h @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace f4ll { +class ioutput_stream +{ +public: + enum class format { dec, hex_padded, hex_trimmed }; + + virtual ioutput_stream &operator<<(format fmt) = 0; + virtual ioutput_stream &operator<<(char const *str) = 0; + virtual ioutput_stream &operator<<(char chr) = 0; + virtual ioutput_stream &operator<<(uint8_t byte) = 0; + virtual ioutput_stream &operator<<(uint16_t ui16) = 0; + virtual ioutput_stream &operator<<(int16_t i16) = 0; + virtual ioutput_stream &operator<<(uint32_t ui32) = 0; + virtual ioutput_stream &operator<<(int32_t i32) = 0; + virtual ~ioutput_stream() = default; +}; +} diff --git a/src/console_handler.cpp b/src/console_handler.cpp index e1955f1..1e56aad 100644 --- a/src/console_handler.cpp +++ b/src/console_handler.cpp @@ -5,6 +5,7 @@ * Author: abody */ +#include "f4ll/output_stream.h" #include #include @@ -130,4 +131,89 @@ void console_handler::print(char const *s) flush(); } +ioutput_stream &console_handler::operator<<(ioutput_stream::format const fmt) +{ + m_fmt = fmt; + return *this; +} + +ioutput_stream &console_handler::operator<<(char const *str) +{ + print(str); + return *this; +} + +ioutput_stream &console_handler::operator<<(char chr) +{ + m_tx_buffer.put(reinterpret_cast(&chr), 1); + flush(); + return *this; +} + +ioutput_stream &console_handler::operator<<(uint8_t byte) +{ + print_unsigned(byte); + return *this; +} + +ioutput_stream &console_handler::operator<<(uint16_t ui16) +{ + return *this; +} + +ioutput_stream &console_handler::operator<<(int16_t i16) +{ + return *this; +} + +ioutput_stream &console_handler::operator<<(uint32_t ui32) +{ + return *this; +} + +ioutput_stream &console_handler::operator<<(int32_t i32) +{ + return *this; +} + +template void console_handler::print_unsigned(T input) +{ + static constexpr uint32_t const divisors[4] = {100, 10000, 10000000, 1000000000}; + T divisor = static_cast(divisors[sizeof(T) - 1]); + + if (m_fmt != ioutput_stream::format::dec) { + append("0x"); + } + if (!input) { + append("0"); + flush(); + return; + } + + T res; + uint8_t cres; + + if (m_fmt == ioutput_stream::format::dec) { + while (divisor) { + res = input / divisor; + if (res) { + cres = static_cast(res + '0'); + m_tx_buffer.put(&cres, 1); + input -= res * divisor; + } + divisor /= 10; + } + } +} + +template void console_handler::print_signed(T input) +{ + if (m_fmt == ioutput_stream::format::dec) { + append("-"); + print_unsigned(-input); + } else { + print_unsigned(input); + } +} + } /* namespace f4ll */