/* * ll_HsUsart.h * * Created on: Oct 29, 2019 * Author: abody */ #ifndef LL_HSUSART_H_ #define LL_HSUSART_H_ #include #include "f4ll/usartcore.h" #include "f4ll/crchandler.h" namespace f4ll { struct DMAINFO; class PacketUsart : public CrcHandler::ICallback, public UsartCore { // friend class UsartCore; public: PacketUsart(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(PacketUsart *caller, uintptr_t userParam, Packet const &packet) = 0; }; // CRCHandler::ICallback interface functions virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, uint8_t task); virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, uint8_t task); void PostPacket(uint8_t const *payload, uint8_t length, bool waitForCrcQueue = true); void SetupReceive(void); void RxProcessed(bool second); // Getters uint8_t* GetTxPacketBuffer(void) { return m_txBuffer.packet.payload; } uint8_t const * GetRxPacketBuffer(bool second) { return m_rxBuffers[second].packet.payload; } USART_TypeDef* GetUsart(void) const { return m_usart; } Stats const & GetStats(void) const { return m_stats; } inline bool IsTxBusy(void) const { return m_txBuffer.busy; } inline bool IsTxFailed(void) const { return m_txBuffer.error; } inline bool IsRxBusy(bool second) const { return m_rxBuffers[second].busy; } inline bool IsRxFailed(bool second) const { return m_rxBuffers[second].error; } 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); // UsartCore pure virtual function implementations virtual void ReceiverIdle(void); virtual void TransmissionComplete(void); virtual void FramingError(void); virtual void Overrun(void); virtual void RxDmaTransferComplete(void); virtual void RxDmaHalfTransfer(void); virtual void RxDmaError(DmaHelper::DmaErrorType reason); virtual void TxDmaTransferComplete(void); virtual void TxDmaHalfTransfer(void); virtual void TxDmaError(DmaHelper::DmaErrorType reason); struct Buffer { Packet packet; //transfer area ends here bool volatile busy = 0; bool volatile 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; 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_ */