skullc-peripherals/Utility/Src/utility_asynchuartlogger.cpp
Erki faa1685e18
All checks were successful
continuous-integration/drone/push Build is passing
Add async UART logger (running on DMA).
2021-03-21 17:03:06 +02:00

74 lines
1.4 KiB
C++

/*
* utility_asynchuartlogger.cpp
*
* Created on: Mar 20, 2021
* Author: erki
*/
#include "utility_asyncaurtlogger.hpp"
#include <cstdlib>
#include <cstdarg>
#include <cassert>
#include "utility_atomicscopeguard.hpp"
namespace Utility
{
AsyncUARTLogger* AsyncUARTLogger::_this = nullptr;
AsyncUARTLogger::AsyncUARTLogger(UART_HandleTypeDef* huart)
: _huart(huart)
{
assert(!_this);
_this = this;
_huart->TxCpltCallback = &AsyncUARTLogger::_txCompleteCallback;
}
void AsyncUARTLogger::log(const char* format, ...)
{
{
AtomicScopeGuard s;
if (_buffer_queue.size() == _buffer_queue.max_size())
return;
}
std::va_list args;
va_start(args, format);
auto tail = _buffer_queue.end();
std::array<char, 255>& buffer = tail->buffer;
tail->length = vsnprintf(buffer.data(), buffer.size(), format, args);
{
AtomicScopeGuard s;
_buffer_queue.increment_tail();
if (!_in_flight)
_sendNextLog();
}
}
void AsyncUARTLogger::_txCompleteCallback(UART_HandleTypeDef*)
{
if (!AsyncUARTLogger::_this->_buffer_queue.empty())
AsyncUARTLogger::_this->_sendNextLog();
else
AsyncUARTLogger::_this->_in_flight = false;
}
void AsyncUARTLogger::_sendNextLog()
{
_in_flight = true;
_Data& head = _buffer_queue.front();
HAL_UART_Transmit_DMA(_huart, reinterpret_cast<uint8_t*>(head.buffer.data()), head.length);
_buffer_queue.pop_front();
}
}