Squash me
This commit is contained in:
parent
b2eee97903
commit
fb4aae99bf
5 changed files with 95 additions and 29 deletions
|
@ -18,12 +18,21 @@ class console_handler : public usart_core, public initialized_singleton<console_
|
||||||
friend class initialized_singleton<console_handler>;
|
friend class initialized_singleton<console_handler>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using size_type = iringbuffer::size_type;
|
||||||
|
class iconsole_input
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void input_available(size_type len) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
void print(char const *s);
|
void print(char const *s);
|
||||||
void flush();
|
void flush();
|
||||||
size_t append(char const *s);
|
size_t append(char const *s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx);
|
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,
|
||||||
|
uint8_t *tx_buffer, size_type tx_buffer_size, iconsole_input *rx_callback);
|
||||||
|
|
||||||
// LL_UsartCore pure virtual function implementations
|
// LL_UsartCore pure virtual function implementations
|
||||||
virtual void receiver_idle(void) override;
|
virtual void receiver_idle(void) override;
|
||||||
|
@ -37,8 +46,12 @@ private:
|
||||||
virtual void tx_dma_half_transfer(void) override;
|
virtual void tx_dma_half_transfer(void) override;
|
||||||
virtual void tx_dma_error(dma_helper::dma_error_type reason) override;
|
virtual void tx_dma_error(dma_helper::dma_error_type reason) override;
|
||||||
|
|
||||||
ringbuffer<128> m_tx_buffer;
|
ringbuffer_ext m_tx_buffer;
|
||||||
iringbuffer::size_type m_in_flight_size = 0;
|
size_type m_bytes_sent = 0;
|
||||||
|
|
||||||
|
ringbuffer_ext m_rx_buffer;
|
||||||
|
size_type m_bytes_requested = 0;
|
||||||
|
iconsole_input *m_rx_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace f4ll */
|
} /* namespace f4ll */
|
||||||
|
|
|
@ -35,22 +35,30 @@ public:
|
||||||
/// without registering the consumption.
|
/// without registering the consumption.
|
||||||
/// The caller should also call report_consumption using the returned
|
/// The caller should also call report_consumption using the returned
|
||||||
/// chunk length after it finished processing the data.
|
/// chunk length after it finished processing the data.
|
||||||
/// @param[in] len_requested Length of the data requested from the buffer.
|
|
||||||
/// The length of the actual data provided
|
|
||||||
/// might be actually smaller (because either reaching the end of
|
|
||||||
/// the buffer or not enough data in the buffer).
|
|
||||||
/// @param[out] data Receives a pointer to the first byte of the available
|
/// @param[out] data Receives a pointer to the first byte of the available
|
||||||
/// data in the buffer
|
/// data in the buffer
|
||||||
/// @param[out] len Receives the length of the chunk available in the buffer.
|
/// @param[out] len Receives the length of the chunk available in the buffer.
|
||||||
/// Will not exceed len_requested.
|
/// Will not exceed len_requested.
|
||||||
/// @retval true if the buffer has more available data, false otherwise.
|
/// @retval true if the buffer has more available data, false otherwise.
|
||||||
virtual bool get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const = 0;
|
virtual bool get_chunk(uint8_t const *&data, size_type &len) const = 0;
|
||||||
|
|
||||||
/// @brief Marks the chunk returned by ringbuffer_GetChunk as available.
|
/// @brief Marks the chunk returned by ringbuffer_GetChunk as available.
|
||||||
/// @param consumed The length of the chunk as returned by
|
/// @param consumed The length of the chunk as returned by
|
||||||
/// ringbuffer_GetChunk(..., len)
|
/// ringbuffer_GetChunk(..., len)
|
||||||
virtual void consumed(size_type len) = 0;
|
virtual void consumed(size_type len) = 0;
|
||||||
|
|
||||||
|
/// @brief Gets a pointer to the next free chunk in the buffer
|
||||||
|
/// @retval Pointer to the beginning of the next free buffer chmemory area
|
||||||
|
/// @param[out] len Receives the length of the returned buffer area.
|
||||||
|
virtual uint8_t *get_free_chunk(size_type &len) = 0;
|
||||||
|
|
||||||
|
/// @brief Registers the data written in the free buffer chunk.
|
||||||
|
/// IMPORTANT: Do not call put() after start modifying the buffer
|
||||||
|
/// returned by get_free_chunk() before registering the written data by
|
||||||
|
/// calling supplied()
|
||||||
|
/// @param len The length of the data written in the buffer
|
||||||
|
virtual bool produced(size_type len) = 0;
|
||||||
|
|
||||||
/// @brief Returns the number of uncommited bytes in the ring buffer.
|
/// @brief Returns the number of uncommited bytes in the ring buffer.
|
||||||
virtual size_type uncommited() const = 0;
|
virtual size_type uncommited() const = 0;
|
||||||
|
|
||||||
|
@ -80,8 +88,13 @@ public:
|
||||||
|
|
||||||
size_type put(uint8_t const *data, size_type len) override;
|
size_type put(uint8_t const *data, size_type len) override;
|
||||||
void commit() override;
|
void commit() override;
|
||||||
bool get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const override;
|
|
||||||
|
bool get_chunk(uint8_t const *&data, size_type &len) const override;
|
||||||
void consumed(size_type len) override;
|
void consumed(size_type len) override;
|
||||||
|
|
||||||
|
uint8_t *get_free_chunk(size_type &len) override;
|
||||||
|
bool produced(size_type len) override;
|
||||||
|
|
||||||
size_type uncommited() const override;
|
size_type uncommited() const override;
|
||||||
size_type commited() const override;
|
size_type commited() const override;
|
||||||
void discard() override;
|
void discard() override;
|
||||||
|
@ -98,6 +111,7 @@ private:
|
||||||
size_type m_tail = 0; //!< Read position
|
size_type m_tail = 0; //!< Read position
|
||||||
|
|
||||||
size_type marker_diff(size_type m1, size_type m2) const;
|
size_type marker_diff(size_type m1, size_type m2) const;
|
||||||
|
size_type max_chunk_len() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -31,6 +31,7 @@ protected:
|
||||||
dma_helper m_tx_dma;
|
dma_helper m_tx_dma;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// these functions are called from interrup context!
|
||||||
virtual void receiver_idle(void) = 0;
|
virtual void receiver_idle(void) = 0;
|
||||||
virtual void transmission_complete(void) = 0;
|
virtual void transmission_complete(void) = 0;
|
||||||
virtual void framing_error(void) = 0;
|
virtual void framing_error(void) = 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Author: abody
|
* Author: abody
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <f4ll/console_handler.h>
|
#include <f4ll/console_handler.h>
|
||||||
#include <f4ll/irq_lock.h>
|
#include <f4ll/irq_lock.h>
|
||||||
#include <f4ll/str_util.h>
|
#include <f4ll/str_util.h>
|
||||||
|
@ -13,24 +14,39 @@
|
||||||
|
|
||||||
namespace f4ll {
|
namespace f4ll {
|
||||||
|
|
||||||
console_handler::console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx)
|
console_handler::console_handler(
|
||||||
: usart_core(usart, dma, stream_rx, stream_tx)
|
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_handler::receiver_idle(void) {}
|
void console_handler::receiver_idle(void)
|
||||||
|
{
|
||||||
|
if (!m_rx_callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint16_t rcvd_bytes = m_bytes_requested - LL_DMA_GetDataLength(m_rx_dma.get_dma(), m_rx_dma.get_stream());
|
||||||
|
size_type len;
|
||||||
|
uint8_t const *data;
|
||||||
|
bool more_data = m_rx_buffer.get_chunk(data, len);
|
||||||
|
m_rx_callback->input_available(len);
|
||||||
|
}
|
||||||
|
|
||||||
void console_handler::transmission_complete(void)
|
void console_handler::transmission_complete(void)
|
||||||
{
|
{
|
||||||
m_tx_buffer.consumed(m_in_flight_size);
|
m_tx_buffer.consumed(m_bytes_sent);
|
||||||
if (m_tx_buffer.commited()) {
|
if (m_tx_buffer.commited()) {
|
||||||
uint8_t const *chunk;
|
uint8_t const *chunk;
|
||||||
m_tx_buffer.get_chunk(m_tx_buffer.size(), chunk, m_in_flight_size);
|
m_tx_buffer.get_chunk(chunk, m_bytes_sent);
|
||||||
if (m_in_flight_size) {
|
if (m_bytes_sent) {
|
||||||
setup_transmit(chunk, m_in_flight_size);
|
setup_transmit(chunk, m_bytes_sent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_in_flight_size = 0;
|
m_bytes_sent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,14 +92,14 @@ void console_handler::flush()
|
||||||
}
|
}
|
||||||
m_tx_buffer.commit();
|
m_tx_buffer.commit();
|
||||||
|
|
||||||
if (m_in_flight_size) {
|
if (m_bytes_sent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t const *chunk;
|
uint8_t const *chunk;
|
||||||
m_tx_buffer.get_chunk(m_tx_buffer.size(), chunk, m_in_flight_size);
|
m_tx_buffer.get_chunk(chunk, m_bytes_sent);
|
||||||
if (m_in_flight_size) {
|
if (m_bytes_sent) {
|
||||||
setup_transmit(chunk, m_in_flight_size);
|
setup_transmit(chunk, m_bytes_sent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,8 @@ void ringbuffer_ext::commit()
|
||||||
m_head = m_head_shadow;
|
m_head = m_head_shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ringbuffer_ext::get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const
|
bool ringbuffer_ext::get_chunk(uint8_t const *&data, size_type &len) const
|
||||||
{
|
{
|
||||||
if (!len_requested) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type head = m_head;
|
size_type head = m_head;
|
||||||
size_type tail = m_tail;
|
size_type tail = m_tail;
|
||||||
size_type chunk_size = head >= tail ? head - tail : m_bsize - tail;
|
size_type chunk_size = head >= tail ? head - tail : m_bsize - tail;
|
||||||
|
@ -64,9 +60,6 @@ bool ringbuffer_ext::get_chunk(size_type len_requested, uint8_t const *&data, si
|
||||||
return tail != head;
|
return tail != head;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk_size > len_requested) {
|
|
||||||
chunk_size = len_requested;
|
|
||||||
}
|
|
||||||
data = m_buffer + tail;
|
data = m_buffer + tail;
|
||||||
len = chunk_size;
|
len = chunk_size;
|
||||||
|
|
||||||
|
@ -89,6 +82,35 @@ void ringbuffer_ext::consumed(size_type len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iringbuffer::size_type ringbuffer_ext::max_chunk_len() const
|
||||||
|
{
|
||||||
|
if (m_tail <= m_head_shadow) {
|
||||||
|
return m_bsize - m_head_shadow;
|
||||||
|
} else {
|
||||||
|
return m_tail - m_head_shadow - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ringbuffer_ext::get_free_chunk(size_type &len)
|
||||||
|
{
|
||||||
|
len = max_chunk_len();
|
||||||
|
|
||||||
|
return m_buffer + m_head_shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ringbuffer_ext::produced(size_type len)
|
||||||
|
{
|
||||||
|
size_type max_len = max_chunk_len();
|
||||||
|
if (len > max_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_head_shadow += len;
|
||||||
|
if (m_head_shadow == m_bsize) {
|
||||||
|
m_head_shadow = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
iringbuffer::size_type ringbuffer_ext::uncommited() const
|
iringbuffer::size_type ringbuffer_ext::uncommited() const
|
||||||
{
|
{
|
||||||
return marker_diff(m_head_shadow, m_head);
|
return marker_diff(m_head_shadow, m_head);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue