/* * utility_asynchuartlogger.cpp * * Created on: Mar 20, 2021 * Author: erki */ #include "utility_asyncaurtlogger.hpp" #include #include #include #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& 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(head.buffer.data()), head.length); _buffer_queue.pop_front(); } }