Implement all stream interface functions on the console handler
This commit is contained in:
parent
c0a28fc242
commit
8abfd9edae
2 changed files with 134 additions and 3 deletions
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <f4ll/initialized_singleton.h>
|
||||
#include <f4ll/output_stream.h>
|
||||
#include <f4ll/ringbuffer.h>
|
||||
#include <f4ll/usart_core.h>
|
||||
|
||||
|
@ -15,7 +16,7 @@
|
|||
|
||||
namespace f4ll {
|
||||
|
||||
class console_handler : public usart_core, public initialized_singleton<console_handler>
|
||||
class console_handler : public initialized_singleton<console_handler>, public usart_core, public ioutput_stream
|
||||
{
|
||||
friend class initialized_singleton<console_handler>;
|
||||
|
||||
|
@ -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 <typename T> void print_unsigned(T input);
|
||||
template <typename T> void print_signed(T input);
|
||||
|
||||
//
|
||||
ringbuffer_ext m_tx_buffer;
|
||||
size_type m_bytes_sent = 0;
|
||||
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
* Author: abody
|
||||
*/
|
||||
|
||||
#include "f4ll/output_stream.h"
|
||||
#include <f4ll/console_handler.h>
|
||||
#include <f4ll/str_util.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
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<uint8_t const *>(&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 <typename T> 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<T>(divisors[sizeof(T) - 1]);
|
||||
bool found = false;
|
||||
|
||||
while (divisor) {
|
||||
res = input / divisor;
|
||||
if (res || found) {
|
||||
cres = static_cast<uint8_t>(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 <typename T> void console_handler::print_signed(T input)
|
||||
{
|
||||
using unsigned_t = typename std::make_unsigned<T>::type;
|
||||
unsigned_t uinput;
|
||||
|
||||
if (m_fmt == ioutput_stream::format::dec && input < 0) {
|
||||
append("-");
|
||||
uinput = static_cast<unsigned_t>(-input);
|
||||
} else {
|
||||
uinput = static_cast<unsigned_t>(input);
|
||||
}
|
||||
print_unsigned(uinput);
|
||||
}
|
||||
|
||||
} /* namespace f4ll */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue