/* * ll_crchandler.h * * Created on: Oct 26, 2019 * Author: compi */ #ifndef LL_CRCHANDLER_H_ #define LL_CRCHANDLER_H_ #include #include #include "f4ll/dmahelper.h" #include "singleton.h" extern "C" void _HandleCrcDmaIrq(void); namespace f4ll { class CrcHandler : public Singleton { friend class Singleton; public: struct ICallback { virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, uint8_t task) = 0; virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, uint8_t task) = 0; }; class SlotBase { friend class CrcHandler; public: struct CrcTask { void const * volatile m_address; // changed to nullptr when execution starts uint16_t volatile m_wordCount; ICallback *m_callback; uintptr_t m_callbackParam; }; private: SlotBase *m_next = nullptr; uint8_t m_taskCount; virtual CrcTask& operator[](int index) = 0; protected: SlotBase(unsigned int taskCount) : m_taskCount(taskCount) {} SlotBase() = delete; SlotBase(SlotBase const &other) = delete; }; template class Slot : public SlotBase { public: Slot() : SlotBase(n) {} virtual CrcTask& operator[](int index) { return m_tasks[index]; } private: Slot::CrcTask m_tasks[n]; }; void AttachSlot(SlotBase &slot); bool Enqueue(SlotBase &slot, uint8_t task, void const *address, uint16_t len, ICallback *cb, uintptr_t cbParam); uint32_t Compute(SlotBase &slot, uint8_t task, void const *address, uint16_t len); bool IsActive(SlotBase &slot, uint8_t task) const; bool IsQueued(SlotBase &slot, uint8_t task) const; bool IsRunning(SlotBase &slot, uint8_t task) const; void DmaTransferCompleted(void); private: CrcHandler(DMA_TypeDef *dma, uint32_t stream); friend void ::_HandleCrcDmaIrq(void); void StartNextTask(void); void WaitResults(SlotBase &slot, uint8_t task) const; DmaHelper m_dma; SlotBase * volatile m_firstSlot = nullptr; SlotBase * volatile m_activeSlot = nullptr; int volatile m_activeTask; }; } // namespace f4ll #endif /* LL_CRCHANDLER_H_ */