
#ifndef _DMA_REGS_H_
#define _DMA_REGS_H_

#include <util/bit_field.h>
#include <cstdint>

#define DMA_REG_START               0x00
#define DMA_REG_CLEAR_INTERRUPT     0x0C
#define DMA_REG_FPGA_ADDRESS        0x10
#define DMA_REG_SC_ADDRESS          0x20
#define DMA_REG_WRITE               0x30
#define DMA_REG_BYTES               0x40

template<uint32_t BASE_ADDR>
class dma_regs {
public:
    // storage declarations
//    BEGIN_BF_DECL(start_t, uint32_t);
//        BF_FIELD(start, 0, 1);
//    END_BF_DECL() r_start;
    uint32_t r_start;

    uint32_t r_address;

    uint32_t r_write;

    uint32_t r_bytes;

    static inline uint32_t& start_reg(){
        return *reinterpret_cast<uint32_t*>(BASE_ADDR+DMA_REG_START);
    }

    static inline uint32_t& clear_interrupt_reg(){
        return *reinterpret_cast<uint32_t*>(BASE_ADDR+DMA_REG_CLEAR_INTERRUPT);
    }

    static inline uint32_t & fpga_address_reg(){
        return *reinterpret_cast<uint32_t*>(BASE_ADDR+DMA_REG_FPGA_ADDRESS);
    }

    static inline uint32_t & sc_address_reg(){
        return *reinterpret_cast<uint32_t*>(BASE_ADDR+DMA_REG_SC_ADDRESS);
    }

    static inline uint32_t & write_reg(){
        return *reinterpret_cast<uint32_t*>(BASE_ADDR+DMA_REG_WRITE);
    }

    static inline uint32_t & bytes_reg(){
        return *reinterpret_cast<uint32_t*>(BASE_ADDR+DMA_REG_BYTES);
    }

};

#endif // _SPN_REGS_H_
