/* * ll_HsUsart.h * * Created on: Oct 29, 2019 * Author: abody */ #ifndef LL_HSUSART_H_ #define LL_HSUSART_H_ #include #include "f4ll/ll_usartcore.h" #include "f4ll/ll_crchandler.h" namespace f4ll { struct DMAINFO; class LL_HsUsart : public LL_CrcHandler::ICallback, public LL_UsartCore { public: LL_HsUsart(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx); struct PacketHeader { // !!! size should be multiple of 4 !!! uint8_t startByte; uint8_t serial; uint8_t payloadLength; uint8_t hash; }; struct Packet { PacketHeader header; uint8_t payload[256+sizeof(uint32_t)]; // extra room for crc32 } __attribute__((aligned)); struct Stats { uint32_t overrun = 0; uint32_t hdrError = 0; uint32_t payloadErrror = 0; uint32_t pep1 = 0; uint32_t pep2 = 0; uint32_t rxDmaError = 0; uint32_t txDmaError = 0; uint32_t rcvd = 0; uint32_t premature_hdr = 0; uint32_t premature_payload = 0; uint32_t sent = 0; uint32_t skiped = 0; }; struct IHsUsartCallback { virtual bool PacketReceived(LL_HsUsart *caller, uintptr_t userParam, Packet const &packet) = 0; }; // LL_CRCHandler::ICallback interface functions virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, int prio); virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, int prio); // LL_UsartCore pure virtual function implementations virtual void ReceiverIdle(void); virtual void TransmissionComplete(void); virtual void RxDmaTransferComplete(void); virtual void RxDmaHalfTransfer(void); virtual void RxDmaError(LL_DmaHelper::DmaErrorType reason); virtual void TxDmaTransferComplete(void); virtual void TxDmaHalfTransfer(void); virtual void TxDmaError(LL_DmaHelper::DmaErrorType reason); void PostPacket(uint8_t const *payload, uint8_t length, bool waitForCrcQueue = true); void SetupReceive(void); void RxProcessed(bool second); uint8_t* GetTxPacketBuffer(void); USART_TypeDef* GetUsart(void); Stats const & GetStats(void); bool IsTxBusy(void); bool IsTxFailed(void); bool IsRxBusy(bool second); bool IsRxFailed(bool second); void SetCallback(IHsUsartCallback* callback, uintptr_t callbackParam); private: void BuildHeader(Packet &packet, uint8_t serialNo, uint8_t length); bool CheckHeader(PacketHeader &header); void SwitchRxBuffers(void); struct Buffer { Packet packet; //transfer area ends here volatile bool busy = 0; volatile bool error = 0; uint16_t requestedLength = 0; uint32_t errorInfo = 0; }; static const uint8_t STARTMARKER = 0x95; uint8_t m_rxSerialNo = -1; uint8_t m_txSerialNo = -1; Stats m_stats; bool m_rxBufferSelector = false; LL_CrcHandler::Slot<2> m_crcSlot; IHsUsartCallback *m_userCallback = nullptr; uintptr_t m_userCallbackParam = 0; Buffer m_txBuffer; Buffer m_rxBuffers[2]; }; } #endif /* LL_HSUSART_H_ */