/* * ll_HsUsart.h * * Created on: Oct 29, 2019 * Author: abody */ #ifndef LL_HSUSART_H_ #define LL_HSUSART_H_ #include #include namespace f4ll { struct DMAINFO; class LL_HsUsart : public LL_CrcHandler::ICallback { 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; uint32_t hdrError; uint32_t payloadErrror; uint32_t pep1, pep2; uint32_t dmaError; uint32_t rcvd; uint32_t premature_hdr; uint32_t premature_payload; uint32_t sent; uint32_t skiped; }; 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); 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(); bool IsTxBusy(); bool IsTxFailed(); bool IsRxBusy(bool second); bool IsRxFailed(bool second); void SetCallback(IHsUsartCallback* callback, uintptr_t callbackParam); static inline void HandleUsartIrq(LL_HsUsart *obj) { obj->UsartIrq(); } static inline void HandleRxDmaIrq(LL_HsUsart *obj) { obj->RxDmaIrq(); } static inline void HandleTxDmaIrq(LL_HsUsart *obj) { obj->TxDmaIrq(); } private: void BuildHeader(Packet &packet, uint8_t serialNo, uint8_t length); bool CheckHeader(PacketHeader &header); void UsartIrq(void); void RxDmaIrq(void); void TxDmaIrq(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; USART_TypeDef *m_usart; LL_DmaHelper m_rxDma; LL_DmaHelper m_txDma; 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_ */