122 lines
3.7 KiB
C++
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];
|
|
};
|
|
|
|
}
|