File mudaq_device.h
File List > libmudaq > mudaq_device.h
Go to the documentation of this file
#ifndef MUDAQ_DEVICE_HPP
#define MUDAQ_DEVICE_HPP
#include <boost/dynamic_bitset.hpp>
#include <cstdint>
#include <string>
#include "../missing_hardware.h"
#include "../registers.h"
#include "mudaq_circular_buffer.hpp"
#include "utils.h"
#if __APPLE__
#define REQUEST_INTERRUPT_COUNTER _IOR(MUDAQ_IOC_TYPE, 1, int)
#define MUDAQ_IOC_TYPE 102
struct mesg {
volatile void* address;
size_t size;
};
#else
#include "../kerneldriver/mudaq.h"
#endif
[[maybe_unused]] static size_t _pagesize(void) {
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
}
int physical_address_check(uint32_t* virtual_address, size_t size);
int is_page_aligned(void* pointer);
void* align_page(void* pointer);
namespace mudaq {
class MudaqDevice {
public:
// a device can exist only once. forbid copying and assignment
MudaqDevice() = delete;
MudaqDevice(const MudaqDevice&) = delete;
MudaqDevice& operator=(const MudaqDevice&) = delete;
MudaqDevice(const std::string& path);
virtual ~MudaqDevice() { close(); }
virtual bool is_ok() const;
virtual bool open();
virtual void close();
virtual bool operator!() const;
virtual void write_register(unsigned idx, uint32_t value);
virtual void write_register_wait(unsigned idx, uint32_t value, unsigned wait_ns);
virtual void toggle_register(unsigned idx, uint32_t value, unsigned wait_ns);
virtual void toggle_register_fast(unsigned idx, uint32_t value);
virtual uint32_t read_register_rw(unsigned idx) const;
virtual uint32_t read_register_ro(unsigned idx) const;
virtual uint32_t read_memory_ro(unsigned idx) const;
virtual uint32_t read_memory_rw(unsigned idx) const;
virtual void write_memory_rw(unsigned idx, uint32_t value);
virtual void write_register_ro_dummy(unsigned idx, uint32_t value);
virtual void write_dummy_acknowledge(unsigned startaddr, unsigned fpga_id);
virtual void read_dummy_acknowledge(unsigned startaddr, int length, unsigned fpga_id);
void enable_led(unsigned which);
void enable_leds(uint8_t pattern);
void disable_leds();
void print_registers();
protected:
volatile uint32_t* mmap_rw(unsigned idx, unsigned len);
volatile uint32_t* mmap_ro(unsigned idx, unsigned len);
void munmap_wrapper(uint32_t** addr, unsigned len, const std::string& error_msg);
void munmap_wrapper(volatile uint32_t** addr, unsigned len, const std::string& error_msg);
// needs to be accessible by the dma readout subtype
int _fd;
private:
const std::string _path;
#ifdef NO_A10_BOARD
uint32_t _regs_rw[64] = {};
uint32_t _regs_ro[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0x20000000, 0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32_t _mem_ro[64 * 1024] = {};
uint32_t _mem_rw[64 * 1024] = {};
uint32_t dummyCounter[64] = {
0, 0xAFFEAFFE, 0xAFFEAFFE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xBEEFBEEF, 0,
};
uint32_t _FEB_REGS[65535] = {};
#else
volatile uint32_t* _regs_rw;
volatile uint32_t* _regs_ro;
volatile uint32_t* _mem_ro;
volatile uint32_t* _mem_rw; // added by DvB for rw mem
#endif
uint16_t _last_read_address; // for reading command of slow control
friend std::ostream& operator<<(std::ostream&, const MudaqDevice&);
};
class DmaMudaqDevice : public MudaqDevice {
public:
typedef CircularBufferProxy<MUDAQ_DMABUF_DATA_ORDER_WORDS> DataBuffer;
typedef CircularSubBufferProxy<MUDAQ_DMABUF_DATA_ORDER_WORDS> DataBlock;
enum { READ_ERROR, READ_TIMEOUT, READ_NODATA, READ_SUCCESS };
// a device can exist only once. forbid copying and assignment
DmaMudaqDevice() = delete;
DmaMudaqDevice(const DmaMudaqDevice&) = delete;
DmaMudaqDevice& operator=(const DmaMudaqDevice&) = delete;
DmaMudaqDevice(const std::string& path);
int enable_continous_readout(int interTrue);
void disable();
virtual bool open();
virtual void close();
virtual bool operator!() const;
int read_block(DataBlock& buffer, volatile uint32_t* pinned_data);
int get_current_interrupt_number(); // via ioctl from driver (no need for
// read_block() function)
uint32_t last_written_addr() const;
uint32_t last_endofevent_addr() const;
private:
volatile uint32_t* _dmabuf_ctrl;
unsigned _last_end_of_buffer;
};
} // namespace mudaq
#endif // __MUDAQ_DEVICE_HPP_WKZIQD9F__