/*
 * ll_dmadrivenusartcore.h
 *
 *  Created on: Nov 4, 2019
 *      Author: abody
 */

#pragma once

#include <platform/usart_ll.h>

#include <f4ll/dma_helper.h>

namespace f4ll {

class usart_core
{
public:
    static inline void usart_isr(usart_core *_this) { _this->usart_isr(); }
    static inline void rx_dma_isr(usart_core *_this) { _this->rx_dma_isr(); }
    static inline void tx_dma_isr(usart_core *_this) { _this->tx_dma_isr(); }

    void setup_transmit(void const *buffer, uint16_t length);
    void setup_receive(void *buffer, uint16_t length);

protected:
    usart_core(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx);

    USART_TypeDef *m_usart;
    dma_helper m_rx_dma;
    dma_helper m_tx_dma;

private:
    virtual void receiver_idle(void) = 0;
    virtual void transmission_complete(void) = 0;
    virtual void framing_error(void) = 0;
    virtual void overrun(void) = 0;

    virtual void rx_dma_transfer_complete(void) = 0;
    virtual void rx_dma_half_transfer(void) = 0;
    virtual void rx_dma_error(dma_helper::dma_error_type reason) = 0;

    virtual void tx_dma_transfer_complete(void) = 0;
    virtual void tx_dma_half_transfer(void) = 0;
    virtual void tx_dma_error(dma_helper::dma_error_type reason) = 0;

public:
    void usart_isr();
    void rx_dma_isr();
    void tx_dma_isr();
};

} /* namespace f4ll */
