nucleo_f446re_playground/components/f4ll/inc/f4ll/packet_usart.h
Attila Body 8e9b69b87a
Rename singleton to initialized_singleton
Use #pragma once instead of guard definitions in every header
2025-06-10 21:57:31 +02:00

122 lines
3.7 KiB
C++

/*
* ll_HsUsart.h
*
* Created on: Oct 29, 2019
* Author: abody
*/
#pragma once
#include <platform/usart_ll.h>
#include <f4ll/crc_handler.h>
#include <f4ll/usart_core.h>
namespace f4ll {
struct DMAINFO;
class packet_usart : public crc_handler::icallback, public usart_core
{
// friend class UsartCore;
public:
packet_usart(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx);
struct packet_header
{ // !!! size should be multiple of 4 !!!
uint8_t start_byte;
uint8_t serial;
uint8_t payload_length;
uint8_t hash;
};
struct packet
{
packet_header header;
uint8_t payload[256 + sizeof(uint32_t)]; // extra room for crc32
} __attribute__((aligned));
struct stats
{
uint32_t overrun = 0;
uint32_t hdr_error = 0;
uint32_t payload_errror = 0;
uint32_t pep1 = 0;
uint32_t pep2 = 0;
uint32_t rx_dma_error = 0;
uint32_t tx_dma_error = 0;
uint32_t rcvd = 0;
uint32_t premature_hdr = 0;
uint32_t premature_payload = 0;
uint32_t sent = 0;
uint32_t skiped = 0;
};
struct ihs_usart_callback
{
virtual bool packet_received(packet_usart *caller, uintptr_t user_param, packet const &packet) = 0;
};
// crc_handler::ICallback interface functions
virtual void crc_succeeded(uintptr_t callback_param, uint32_t crc, uint8_t task) override;
virtual void crc_failed(uintptr_t callback_param, uint32_t crc, uint8_t task) override;
void post_packet(uint8_t const *payload, uint8_t length, bool wait_for_crc_queue = true);
void setup_receive(void);
void rx_processed(bool second);
// Getters
uint8_t *get_tx_packet_buffer(void) { return m_tx_buffer.pkt.payload; }
uint8_t const *get_rx_packet_buffer(bool second) { return m_rx_buffers[second].pkt.payload; }
USART_TypeDef *get_usart(void) const { return m_usart; }
stats const &get_stats(void) const { return m_stats; }
inline bool is_tx_busy(void) const { return m_tx_buffer.busy; }
inline bool is_tx_failed(void) const { return m_tx_buffer.error; }
inline bool is_rx_busy(bool second) const { return m_rx_buffers[second].busy; }
inline bool is_rx_failed(bool second) const { return m_rx_buffers[second].error; }
void set_callback(ihs_usart_callback *callback, uintptr_t callback_param);
private:
void build_header(packet &packet, uint8_t serial_nr, uint8_t length);
bool check_header(packet_header &header);
void switch_rx_buffers(void);
// UsartCore pure virtual function implementations
virtual void receiver_idle(void) override;
virtual void transmission_complete(void) override;
virtual void framing_error(void) override;
virtual void overrun(void) override;
virtual void rx_dma_transfer_complete(void) override;
virtual void rx_dma_half_transfer(void) override;
virtual void rx_dma_error(dma_helper::dma_error_type reason) override;
virtual void tx_dma_transfer_complete(void) override;
virtual void tx_dma_half_transfer(void) override;
virtual void tx_dma_error(dma_helper::dma_error_type reason) override;
struct Buffer
{
packet pkt;
// transfer area ends here
bool volatile busy = 0;
bool volatile error = 0;
uint16_t requested_length = 0;
uint32_t error_info = 0;
};
static const uint8_t STARTMARKER = 0x95;
uint8_t m_rx_serial_nr = -1;
uint8_t m_tx_serial_nr = -1;
stats m_stats;
bool m_rx_buffer_selector = false;
crc_handler::slot<2> m_crc_slot;
ihs_usart_callback *m_user_callback = nullptr;
uintptr_t m_user_callback_param = 0;
Buffer m_tx_buffer;
Buffer m_rx_buffers[2];
};
}