Commit c486f226 authored by Michal Dziewiecki's avatar Michal Dziewiecki

HEL updates to ebPy: cycle operations, per-operation bus format.

parent 83797a1c
EB_PATH = ..
EB_PATH = ../../../bel_projects/ip_cores/etherbone-core/api
EB_INCPATH = $(EB_PATH)/include
BUILD_PATH = .
INC_PATH = $(BUILD_PATH)/inc
......@@ -6,8 +7,8 @@ SRC_PATH = $(BUILD_PATH)/src
EB_LIB = etherbone
#works with python 2 and 3. Set to your python lib and include directory
PY_LIB = python3.6m
PY_INCPATH = /usr/include/python3.6m
PY_LIB = python3.10
PY_INCPATH = /usr/include/python3.10
PREFIX ?= /usr/local
INSTALLPATH = $(PREFIX)/bin
......
......@@ -3,14 +3,24 @@
%include std_string.i
%include typemaps.i
%include cpointer.i
%include std_vector.i
// Make etherbone_wrap.cxx include this header:
%{
#include "ebwrapper.h"
%}
// Instantiate possible versions of std::vector used
namespace std {
%template(vectori) vector<int>;
%template(vectoru) vector<unsigned>;
%template(vectorl) vector<long>;
%template(vectorul) vector<unsigned long>;
};
// Make SWIG look into this header:
%include "ebwrapper.h"
// Make etherbone_wrap.cxx include this header:
%{
#include "ebwrapper.h"
%}
# Defines used by the etherbone library - translated from etherbone.h
from enum import IntEnum
class ebStatus(IntEnum):
EB_OK = 0 # success
EB_FAIL = -1 # system failure
EB_ADDRESS = -2 # invalid address
EB_WIDTH = -3 # impossible bus width
EB_OVERFLOW = -4 # cycle length overflow
EB_ENDIAN = -5 # remote endian required
EB_BUSY = -6 # resource busy
EB_TIMEOUT = -7 # timeout
EB_OOM = -8 # out of memory
EB_ABI = -9 # library incompatible with application
EB_SEGFAULT = -10 # one or more operations failed
class ebFormat(IntEnum):
EB_DATA8 = 0x01
EB_DATA16 = 0x02
EB_DATA32 = 0x04
EB_DATA64 = 0x08
EB_DATAX = 0x0f
EB_ADDR8 = 0x10
EB_ADDR16 = 0x20
EB_ADDR32 = 0x40
EB_ADDR64 = 0x80
EB_ADDRX = 0xf0
EB_ENDIAN_MASK = 0x30
EB_BIG_ENDIAN = 0x10
EB_LITTLE_ENDIAN = 0x20
EB_DESCRIPTOR_IN = 0x01
EB_DESCRIPTOR_OUT = 0x02
import eb
from ebdef import ebStatus, ebFormat
ebobj = eb.EbWrapper()
ebobj.connect("dev/ttyUSB0")
vendorID = 0x0000000000000651
productID = 0x10040200
prioAdr = ebobj.findById(vendorID, productID)
print("prioadr 0x%8x " % (prioAdr))
print("1st word ram 0x%8x" % ebobj.read(0x4120000))
if (ebobj.connect("dev/wbm0")):
print("ebobj connect OK")
vendorID = 0x000000000000ce42
#vendorID = 0x0000000000000651
productID = 0xde0d8ced
#productID = 0x10040200
ioAdr = ebobj.findById(vendorID, productID)
print("WR PPS Addr: 0x%08x " % (ioAdr))
#print("1st word 0x%08x" % ebobj.read(ioAdr+8))
addr = [ioAdr, ioAdr+4, ioAdr+8, ioAdr+12]
data = ebobj.readCycleEx(addr, ebFormat.EB_DATA32 | ebFormat.EB_ADDR32)
print("Data: ", data)
timestamp = (data[3] & 0xFF)*(1<<32) + data[2] + data[1]*8e-9;
print("Timestamp: ", timestamp);
else:
print("ebobj connect ERROR")
print("Finished.")
......@@ -6,6 +6,9 @@
#include <string>
#include <inttypes.h>
#include <memory>
#include <vector>
#define STD_BUSFMT 0xFF //EB_DATAX | EB_ADDRX
class EbWrapper {
......@@ -19,11 +22,16 @@ public:
~EbWrapper();
bool connect(const std::string& ebdevname);
bool connectEx(const std::string& ebdevname, int busfmt = STD_BUSFMT);
bool disconnect(); //Close connection
//bool writeCycle(std::vector<unsigned> vVal) const;
void write(const unsigned addr, const unsigned value) const;
//std::vector<unsigned> readCycle(std::vector<unsigned> vAddr) const;
void writeEx(const unsigned addr, const unsigned value, int busfmt = STD_BUSFMT) const;
void writeCycle(std::vector<unsigned> addr, std::vector<unsigned> value) const;
void writeCycleEx(std::vector<unsigned> addr, std::vector<unsigned> value, int busfmt = STD_BUSFMT) const;
std::vector<unsigned long> readCycle(std::vector<unsigned> vAddr) const;
std::vector<unsigned long> readCycleEx(std::vector<unsigned> vAddr, int busfmt = STD_BUSFMT) const;
unsigned read(const unsigned addr) const;
unsigned readEx(const unsigned addr, int busfmt = STD_BUSFMT) const;
unsigned findById(const unsigned long vendor, const unsigned id);
};
......
......@@ -29,12 +29,12 @@ public:
EbWrapperImpl();
~EbWrapperImpl();
bool connect(const std::string& ebdevname);
bool connect(const std::string& ebdevname, eb_format_t busformat);
bool disconnect(); //Close connection
//bool writeCycle(std::vector<unsigned> vVal) const;
void write(const unsigned addr, const unsigned value);
//std::vector<unsigned> readCycle(std::vector<unsigned> vAddr) const;
unsigned read(const unsigned addr);
void write(const unsigned addr, const unsigned value, eb_format_t busformat);
void writeCycle(const std::vector<unsigned> &addr, const std::vector<unsigned> &value, eb_format_t busformat) const;
unsigned read(const unsigned addr, eb_format_t busformat);
std::vector<unsigned long> readCycle(const std::vector<unsigned> &vAddr, eb_format_t busformat) const;
unsigned findById(const unsigned long vendor, const unsigned id);
};
......
......@@ -5,8 +5,24 @@
EbWrapper::~EbWrapper() = default;
// Etherbone interface
bool EbWrapper::connect(const std::string& en) {return impl_->connect(en);} //Open connection to a DM via Etherbone
bool EbWrapper::connect(const std::string& en) {return impl_->connect(en, EB_ADDRX|EB_DATAX);} //Open connection to a DM via Etherbone
bool EbWrapper::connectEx(const std::string& en, int busfmt) {return impl_->connect(en, busfmt);} //Open connection to a DM via Etherbone
bool EbWrapper::disconnect() {return impl_->disconnect();} //Close connection
void EbWrapper::write(const unsigned addr, const unsigned value) const {return impl_->write(addr, value);} //Open connection to a DM via Etherbone
unsigned EbWrapper::read(const unsigned addr) const {return impl_->read(addr);} //Close connection
unsigned EbWrapper::findById(const unsigned long vendor, const unsigned id) {return impl_->findById(vendor, id);}
\ No newline at end of file
void EbWrapper::write(const unsigned addr, const unsigned value) const {return impl_->write(addr, value, EB_ADDRX|EB_DATAX);}
void EbWrapper::writeEx(const unsigned addr, const unsigned value, int busfmt) const
{return impl_->write(addr, value, busfmt);}
void EbWrapper::writeCycle(std::vector<unsigned> addr, std::vector<unsigned> value) const {return impl_->writeCycle(addr, value, EB_ADDRX|EB_DATAX);}
void EbWrapper::writeCycleEx(std::vector<unsigned> addr, std::vector<unsigned> value, int busfmt) const
{return impl_->writeCycle(addr, value, busfmt);}
unsigned EbWrapper::read(const unsigned addr) const {return impl_->read(addr, EB_ADDRX|EB_DATAX);}
unsigned EbWrapper::readEx(const unsigned addr, int busfmt) const {return impl_->read(addr, busfmt);}
std::vector<unsigned long> EbWrapper::readCycle(std::vector<unsigned> vAddr) const {return impl_->readCycle(vAddr, EB_ADDRX|EB_DATAX);}
std::vector<unsigned long> EbWrapper::readCycleEx(std::vector<unsigned> vAddr, int busfmt) const
{return impl_->readCycle(vAddr, busfmt);}
unsigned EbWrapper::findById(const unsigned long vendor, const unsigned id) {return impl_->findById(vendor, id);}
\ No newline at end of file
#include "ebwrapper_impl.h"
//Standard bus format: EB_DATAX|EB_ADDRX
EbWrapper::EbWrapperImpl::EbWrapperImpl() {}
EbWrapper::EbWrapperImpl::~EbWrapperImpl() {}
bool EbWrapper::EbWrapperImpl::connect(const std::string& dev) {
bool EbWrapper::EbWrapperImpl::connect(const std::string& dev, eb_format_t busfmt) {
ebdevname = dev;
bool ret;
try {
ebs.open(0, EB_DATAX|EB_ADDRX);
ebd.open(ebs, ebdevname.c_str(), EB_DATAX|EB_ADDRX, 3);
ebs.open(0, busfmt);
ebd.open(ebs, ebdevname.c_str(), busfmt, 3);
ret = true;
} catch (etherbone::exception_t const& ex) {
ret = false;
......@@ -29,32 +31,36 @@ bool EbWrapper::EbWrapperImpl::connect(const std::string& dev) {
return ret;
}
void EbWrapper::EbWrapperImpl::write(const unsigned addr, const unsigned value) {
ebd.write((eb_address_t)addr, EB_DATAX|EB_ADDRX, (eb_data_t)value);
void EbWrapper::EbWrapperImpl::write(const unsigned addr, const unsigned value, eb_format_t busfmt) {
ebd.write((eb_address_t)addr, busfmt, (eb_data_t)value);
}
//std::vector<unsigned> readCycle(std::vector<unsigned> vAddr) const;
unsigned EbWrapper::EbWrapperImpl::read(const unsigned addr) {
unsigned EbWrapper::EbWrapperImpl::read(const unsigned addr, eb_format_t busfmt) {
eb_data_t ret;
ebd.read((eb_address_t)addr, EB_DATAX|EB_ADDRX, (eb_data_t*)&ret);
ebd.read((eb_address_t)addr, busfmt, (eb_data_t*)&ret);
return (unsigned)ret;
}
/*
void EbWrapper::EbWrapperImpl::write(const std::vector<unsigned> addr&, const std::vector<unsigned> value&) {
Cycle cyc;
void EbWrapper::EbWrapperImpl::writeCycle(const std::vector<unsigned> &addr, const std::vector<unsigned> &value, eb_format_t busfmt) const {
Cycle cyc;
cyc.open(ebd);
if addr.size() != value.size() throw std::runtime_error("Address and value vectors must be the same size");
for (auto& [a, v] : zip(addr, value)) {cyc.write((eb_address_t)a, EB_DATAX|EB_ADDRX, (eb_data_t)v);}
//If address and data vector sizes don't match, use the smaller one
unsigned size = addr.size();
if (value.size() < size) size = value.size();
for (unsigned long i = 0; i < size; i++)
cyc.write((eb_address_t)addr[i], busfmt, (eb_data_t)value[i]);
cyc.close();
}
//std::vector<unsigned> readCycle(std::vector<unsigned> vAddr) const;
unsigned EbWrapper::EbWrapperImpl::read(const unsigned addr) {
eb_data_t ret;
ebd.read((eb_address_t)addr, EB_DATAX|EB_ADDRX, (eb_data_t*)&ret);
return (unsigned)ret;
std::vector<unsigned long> EbWrapper::EbWrapperImpl::readCycle(const std::vector<unsigned> &vAddr, eb_format_t busfmt) const {
std::vector<unsigned long> result(vAddr.size(), 0);
Cycle cyc;
cyc.open(ebd);
for (unsigned long i = 0; i < result.size(); i++)
cyc.read(vAddr[i], busfmt, &(result[i]));
cyc.close();
return result;
}
*/
unsigned EbWrapper::EbWrapperImpl::findById(const unsigned long vendor, const unsigned id) {
std::vector<struct sdb_device> devs;
......@@ -65,4 +71,4 @@ bool EbWrapper::EbWrapperImpl::connect(const std::string& dev) {
if (cnt > 0) retAdr = devs[0].sdb_component.addr_first;
return retAdr;
}
\ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment