From 80fc520b6fad8a012e239efca77f33f759337344 Mon Sep 17 00:00:00 2001 From: Attila Body Date: Sun, 29 Jun 2025 21:54:20 +0200 Subject: [PATCH 1/3] WIP --- inc/f4ll/console_handler.h | 23 +++++++++- src/console_handler.cpp | 86 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 2 deletions(-) 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/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 */ From 8abfd9edaeb3f0848f49a7772355116c0d699966 Mon Sep 17 00:00:00 2001 From: Attila Body Date: Sun, 29 Jun 2025 21:54:20 +0200 Subject: [PATCH 2/3] Implement all stream interface functions on the console handler --- inc/f4ll/console_handler.h | 23 +++++++- src/console_handler.cpp | 114 ++++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 3 deletions(-) diff --git a/inc/f4ll/console_handler.h b/inc/f4ll/console_handler.h index 14e15a6..5f76c90 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; @@ -34,6 +35,16 @@ public: iringbuffer &get_rx_buffer() { return m_rx_buffer; } + // 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; + private: console_handler( USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, uint8_t *rx_buffer, size_type x_buffer_size, @@ -41,7 +52,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 +64,14 @@ private: void tx_dma_half_transfer(void) override; void tx_dma_error(dma_helper::dma_error_type reason) 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/src/console_handler.cpp b/src/console_handler.cpp index e1955f1..9ff43e7 100644 --- a/src/console_handler.cpp +++ b/src/console_handler.cpp @@ -5,10 +5,12 @@ * Author: abody */ +#include "f4ll/output_stream.h" #include #include #include +#include namespace f4ll { @@ -36,7 +38,7 @@ void console_handler::receiver_idle(void) { uint16_t rcvd_bytes = m_bytes_requested - m_reqd_bytes_registered - LL_DMA_GetDataLength(m_rx_dma.get_dma(), m_rx_dma.get_stream()); if (rcvd_bytes) { - m_reqd_bytes_registered += rcvd_bytes; + m_reqd_bytes_registered += rcvd_bytes; m_rx_buffer.produced(rcvd_bytes); m_rx_buffer.commit(); if (m_rx_callback) { @@ -130,4 +132,114 @@ 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) +{ + print_unsigned(ui16); + return *this; +} + +ioutput_stream &console_handler::operator<<(int16_t i16) +{ + print_signed(i16); + return *this; +} + +ioutput_stream &console_handler::operator<<(uint32_t ui32) +{ + print_unsigned(ui32); + return *this; +} + +ioutput_stream &console_handler::operator<<(int32_t i32) +{ + print_signed(i32); + return *this; +} + +template void console_handler::print_unsigned(T input) +{ + 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) { + static constexpr uint32_t const divisors[4] = {100, 10000, 10000000, 1000000000}; + T divisor = static_cast(divisors[sizeof(T) - 1]); + bool found = false; + + while (divisor) { + res = input / divisor; + if (res || found) { + cres = static_cast(res + '0'); + m_tx_buffer.put(&cres, 1); + input -= res * divisor; + found = true; + } + divisor /= 10; + } + } else { + uint8_t nibbles = sizeof(T) * 2; + bool found = false; + do { + uint8_t shift = (nibbles - 1) * 4; + T mask = 0xf << shift; + uint8_t bin = (input & mask) >> shift; + uint8_t chr = bin <= 9 ? bin + '0' : bin - 10 + 'A'; + if (!found && !bin && m_fmt == ioutput_stream::format::hex_trimmed) { + continue; + } + found = true; + m_tx_buffer.put(&chr, 1); + } while (--nibbles); + } + flush(); +} + +template void console_handler::print_signed(T input) +{ + using unsigned_t = typename std::make_unsigned::type; + unsigned_t uinput; + + if (m_fmt == ioutput_stream::format::dec && input < 0) { + append("-"); + uinput = static_cast(-input); + } else { + uinput = static_cast(input); + } + print_unsigned(uinput); +} + } /* namespace f4ll */ From 562ad3229e085904547b943e14181c10f36eb5f8 Mon Sep 17 00:00:00 2001 From: Attila Body Date: Tue, 1 Jul 2025 15:18:01 +0200 Subject: [PATCH 3/3] Insignificant formatting change --- .clang-format | 9 +++------ src/console_handler.cpp | 8 ++++---- src/dma_helper.cpp | 10 +++++----- src/ringbuffer.cpp | 4 ++-- src/usart_core.cpp | 6 +++--- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/.clang-format b/.clang-format index 624e7ab..d420259 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ IndentWidth: 4 TabWidth: 4 BreakBeforeBraces: Custom AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: true +AllowShortBlocksOnASingleLine: false AllowShortLambdasOnASingleLine: true AllowAllArgumentsOnNextLine: true IndentCaseLabels: true @@ -13,15 +13,12 @@ NamespaceIndentation: None FixNamespaceComments: false PackConstructorInitializers: Never AlignAfterOpenBracket: AlwaysBreak +BreakConstructorInitializersBeforeComma: true InsertBraces: true -SpaceBeforeParens: Custom -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterFunctionDefinitionName: false BraceWrapping: AfterClass: true # false AfterControlStatement: false - AfterEnum: false # false + AfterEnum: true # false AfterFunction: true # false AfterNamespace: false AfterObjCDeclaration: true # false diff --git a/src/console_handler.cpp b/src/console_handler.cpp index 9ff43e7..60f17d7 100644 --- a/src/console_handler.cpp +++ b/src/console_handler.cpp @@ -17,10 +17,10 @@ namespace f4ll { console_handler::console_handler( USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, uint8_t *rx_buffer, size_type rx_buffer_size, uint8_t *tx_buffer, size_type tx_buffer_size, iconsole_input *rx_callback) - : usart_core(usart, dma, stream_rx, stream_tx), - m_tx_buffer(tx_buffer, tx_buffer_size), - m_rx_buffer(rx_buffer, rx_buffer_size), - m_rx_callback(rx_callback) + : usart_core(usart, dma, stream_rx, stream_tx) + , m_tx_buffer(tx_buffer, tx_buffer_size) + , m_rx_buffer(rx_buffer, rx_buffer_size) + , m_rx_callback(rx_callback) { LL_USART_EnableIT_IDLE(usart); LL_USART_EnableIT_ERROR(usart); diff --git a/src/dma_helper.cpp b/src/dma_helper.cpp index 42e2e11..96d643d 100644 --- a/src/dma_helper.cpp +++ b/src/dma_helper.cpp @@ -10,12 +10,12 @@ q * ll_dmahelper.cpp namespace f4ll { dma_helper::dma_helper(DMA_TypeDef *dma, uint32_t stream) - : m_dma(dma), - m_stream(stream), - m_is_reg( + : m_dma(dma) + , m_stream(stream) + , m_is_reg( (dma == DMA1) ? ((m_stream < LL_DMA_STREAM_4) ? &DMA1->LISR : &DMA1->HISR) - : ((m_stream < LL_DMA_STREAM_4) ? &DMA2->LISR : &DMA2->HISR)), - m_ifc_reg( + : ((m_stream < LL_DMA_STREAM_4) ? &DMA2->LISR : &DMA2->HISR)) + , m_ifc_reg( (dma == DMA1) ? ((m_stream < LL_DMA_STREAM_4) ? &DMA1->LIFCR : &DMA1->HIFCR) : ((m_stream < LL_DMA_STREAM_4) ? &DMA2->LIFCR : &DMA2->HIFCR)) { diff --git a/src/ringbuffer.cpp b/src/ringbuffer.cpp index ae81ac2..a665a5a 100644 --- a/src/ringbuffer.cpp +++ b/src/ringbuffer.cpp @@ -5,8 +5,8 @@ namespace f4ll { ringbuffer_ext::ringbuffer_ext(uint8_t *bptr, size_type bsize) - : m_buffer(bptr), - m_bsize(bsize) + : m_buffer(bptr) + , m_bsize(bsize) { } diff --git a/src/usart_core.cpp b/src/usart_core.cpp index c0051d6..f4be7cf 100644 --- a/src/usart_core.cpp +++ b/src/usart_core.cpp @@ -10,9 +10,9 @@ namespace f4ll { usart_core::usart_core(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t streamRx, uint32_t streamTx) - : m_usart(usart), - m_rx_dma(dma, streamRx), - m_tx_dma(dma, streamTx) + : m_usart(usart) + , m_rx_dma(dma, streamRx) + , m_tx_dma(dma, streamTx) { uint32_t status = usart->SR; volatile uint32_t tmpreg = usart->DR; // clearing some of the error/status bits in the USART