• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

abbplugin/src/ABBdaemon.cxx (r4864/r2882)

Go to the documentation of this file.
00001 #include "ABBdaemon.h"
00002 
00003 #include "mprace/ABB.h"
00004 #include "mprace/DMABuffer.h"
00005 
00006 #include "abbdaemon/CTLpacket.h"
00007 #include "abbdaemon/CTLresponse.h"
00008 
00009 #include <iostream>
00010 //#include <stdio.h>
00011 using namespace std;
00012 
00013 // These are FPGA registers
00014 #define DID                     (0x0000 >> 2)
00015 #define GSR                     (0x0020 >> 2)
00016 #define CTL_H2R                 (0x00A0 >> 2)
00017 #define CTL_R2H                 (0x00A0 >> 2)
00018 #define DLM_H2R                 (0x00A4 >> 2)
00019 #define DLM_R2H                 (0x00A4 >> 2)
00020 #define CTL_STATUS              (0x00AC >> 2)
00021 #define CTL_CONTROL             (0x00AC >> 2)
00022 
00023 #define EVENT_BUFFER_STATUS     (0x0090 >> 2)
00024 
00025 #define CTL_PACKET_AVAIL        (0x00000001)
00026 #define CTL_FIFO_RESET          (0x0A)
00027 #define EVENT_BUFFER_RESET      (0x0A)
00028 #define CTL_EOP                 (0x10000)
00029 #define CTL_SOP                 (0x20000)
00030 #define CTL_MASK                (0x0000FFFF)
00031 #define DLM_VALID               (0x00020000)
00032 #define DLM_MASK                (0x0000000F)
00033 
00034 
00035 
00036 abbdaemon::ABBdaemonClient::ABBdaemonClient(const char*, int role)
00037 {
00038    try {
00039       board = new mprace::ABB(0);
00040    } catch (...) {
00041       board = 0;
00042       std::cerr << "Could not create ABB board. Is the driver properly loaded?" << std::endl;
00043    }
00044 
00045    debug = 0;
00046 
00047 }
00048 
00049 abbdaemon::ABBdaemonClient::~ABBdaemonClient()
00050 {
00051    delete board;
00052    board = 0;
00053 }
00054 
00055 void abbdaemon::ABBdaemonClient::enableDebugMessages(bool enable)
00056 {
00057    debug = enable ? &std::cout : 0;
00058 }
00059 
00060 uint32_t abbdaemon::ABBdaemonClient::submitReset(uint32_t what)
00061 {
00062    if (board==0) return 1;
00063 
00064    if (debug) (*debug) << "Client wants to reset " << what << endl;
00065    if (what == RESET_ALL || what == RESET_CTL_FIFO) {
00066       if (debug) (*debug) << "Resetting CTL_FIFO" << endl;
00067       board->setReg(CTL_CONTROL, CTL_FIFO_RESET);
00068    }
00069 
00070    if (what == RESET_ALL || what == RESET_ABB) {
00071       if (debug) (*debug) << "Resetting eventbuffer" << endl;
00072       board->setReg(EVENT_BUFFER_STATUS, EVENT_BUFFER_RESET);
00073    }
00074 
00075    if (what == RESET_ALL || what == RESET_FIFO_TIMEOUT) {
00076       if (debug) (*debug) << "Resetting FIFO timeout flag" << endl;
00077       board->setReg(0x1E, 0x0A);
00078    }
00079 
00080    if (debug) (*debug) << "After reset status is: "
00081          << hex << board->getReg(CTL_STATUS) << dec << endl;
00082 
00083    if (debug) (*debug) << "General status register is: "
00084          << hex << board->getReg(GSR) << dec << endl;
00085 
00086    return 0;
00087 }
00088 
00089 uint32_t abbdaemon::ABBdaemonClient::submitNOper(uint32_t rocid, uint32_t retid, int t_number,
00090                                                   uint32_t *addrs, uint32_t *values,  uint32_t *retvals)
00091 {
00092    if (board==0) return 1;
00093 
00094    uint32_t retcode = 0;
00095    
00096 //   printf("submitNOper rocid = %x retid = %x noper = %d\n", rocid, retid, t_number);
00097    
00098  while ((t_number > 0) && (retcode==0)) {
00099 
00100    CTLpacket packet(rocid, retid);
00101    
00102    int number = t_number;
00103    if (number > 6) number = 6;
00104 
00105    for (int i = 0; i < number; i++) {
00106       uint32_t addr = addrs[i];
00107 
00108 //      printf("   oper:%s addr[%d] = 0x%08x\n", (addrs[i] & 0x80000000 ? "PUT" : "GET"), i, addr & 0x7fffffff);
00109 
00110       /* Ignore the MSB */
00111       addr &= 0x7FFFFFFF;
00112       if (debug) (*debug) << i << " : " << addr << " = " << values[i] << endl;
00113 
00114       if (addrs[i] & 0x80000000)
00115          packet.add(CTLcommand(PUT, addr, values[i]));
00116       else
00117          packet.add(CTLcommand(GET, addr));
00118    }
00119 
00120    std::list<CTLresponse*> replies = packet.send(board);
00121 
00122    if (replies.size()==0) retcode = 2;
00123 
00124    std::list<CTLresponse*>::iterator iter = replies.begin();
00125    int i = 0;
00126 
00127    while (iter!=replies.end()) {
00128 
00129       CTLresponse* r = *iter++;
00130 
00131       CTLpacket::CTLcmd expected = ((addrs[i] & 0x80000000) ?
00132                            CTLpacket::ACKPUT :
00133                            CTLpacket::ACKGET);
00134 
00135       if (r->getCTLcmd() != expected) {
00136          retcode = 1;
00137          if (expected == CTLpacket::ACKGET)
00138             values[i] = -1;
00139          if (debug) (*debug) << "getCTLcmd = " << r->getCTLcmd() << ", expected = " << expected << endl;
00140          if (retvals) retvals[i] = -(r->getErrorCode());
00141          if (debug) (*debug) << "getErrorCode = " << r->getErrorCode() << ", value = " << -(r->getErrorCode()) << endl;
00142       } else {
00143          if (expected == CTLpacket::ACKGET)
00144             values[i] = r->getValue();
00145 
00146          if (retvals) retvals[i] = 0;
00147       }
00148 
00149       delete r;
00150       i++;
00151    }
00152      t_number -= number;
00153      addrs+=number;
00154      values+=number;
00155      retvals+=number;
00156 //     if (t_number>0) printf("  Rest packet = %d\n", t_number);
00157  } 
00158 
00159  return retcode;
00160 }
00161 
00162 uint32_t abbdaemon::ABBdaemonClient::submitPut(uint32_t rocid, uint32_t retid, uint32_t addr, uint32_t value)
00163 {
00164    addr |= 0x80000000;
00165    return submitNOper(rocid, retid, 1, &addr, &value, 0);
00166 }
00167 
00168 uint32_t abbdaemon::ABBdaemonClient::submitNPut(uint32_t rocid, uint32_t retid, int number,
00169                                                  uint32_t *addrs, uint32_t *values, uint32_t *retvals)
00170 {
00171    for (int i=0;i<number;i++) addrs[i] |= 0x80000000;
00172 
00173    uint32_t retcode = submitNOper(rocid, retid, number, addrs, values, retvals);
00174 
00175    for (int i=0;i<number;i++) addrs[i] &= 0x7FFFFFFF;
00176 
00177    return retcode;
00178 }
00179 
00180 uint32_t abbdaemon::ABBdaemonClient::submitGet(uint32_t rocid, uint32_t retid, uint32_t addr, uint32_t *value)
00181 {
00182    return submitNOper(rocid, retid, 1, &addr, value, 0);
00183 }
00184 
00185 uint32_t abbdaemon::ABBdaemonClient::submitNGet(uint32_t rocid, uint32_t retid, int number,
00186                                                  uint32_t *addrs, uint32_t *values, uint32_t *retvals)
00187 {
00188    return submitNOper(rocid, retid, number, addrs, values, retvals);
00189 }
00190 
00191 uint32_t abbdaemon::ABBdaemonClient::submitPutDLM(uint32_t value)
00192 {
00193    if (board==0) return 1;
00194    if (debug) (*debug) << "Requested DLM put with value: " << value << endl;
00195 
00196    try {
00197       board->setReg(DLM_H2R, (value & DLM_MASK) );
00198    } catch (mprace::Exception &e) {
00199       return 1;
00200    }
00201 
00202    return 0;
00203 }
00204 
00205 uint32_t abbdaemon::ABBdaemonClient::submitGetDLM(uint32_t *retvalue)
00206 {
00207    if (board==0) return 1;
00208 
00209    try {
00210       volatile unsigned int valid;
00211       unsigned int value;
00212 
00213       if (debug) (*debug) << "Waiting for incoming data: " << flush;
00214 
00215       do {
00216          value = board->getReg(DLM_R2H);
00217          valid = (value & DLM_VALID);
00218          if (debug) (*debug) << "." << flush;
00219       } while (valid == 0);
00220 
00221       if (debug) (*debug) << " got a DLM!" << endl;
00222       if (debug) (*debug) << "Got DLM message: " << hex << value << dec << endl;
00223 
00224       if (retvalue) *retvalue = (value & DLM_MASK);
00225    } catch (mprace::Exception &e) {
00226       return 1;
00227    }
00228 
00229    return 0;
00230 }
00231 
00232 uint32_t abbdaemon::ABBdaemonClient::readDMAserialized(const unsigned int address,
00233                            DMABUFFER_HANDLE buffer_handle, const unsigned int count,
00234                            const unsigned int offset, const bool inc,
00235                            const bool lock, const float timeout)
00236 {
00237    if (board==0) return 1;
00238 
00239    try {
00240       board->readDMAFIFO(address, *reinterpret_cast<mprace::DMABuffer*>(buffer_handle), count, offset, inc, lock, timeout);
00241       if (debug) (*debug) << "FIFO status: " << hex << board->getReg(0x24) << dec << endl;
00242       //if (lock) this->syncBuffer(buffer_handle); // already done in readDMAFIFO JAM
00243    } catch (mprace::Exception &e) {
00244       cerr << "Something failed" << endl;
00245       return 1;
00246    }
00247 
00248    return 0;
00249 }
00250 
00251 abbdaemon::DMABUFFER_HANDLE abbdaemon::ABBdaemonClient::registerBuffer(unsigned int len, void *address)
00252 {
00253    if (debug) (*debug) << "Registering buffer at " << address << " of size " << len << endl;
00254 
00255    mprace::DMABuffer *buffer = new mprace::DMABuffer(*board, len, (unsigned int*)address);
00256 
00257    return (DMABUFFER_HANDLE) buffer;
00258 }
00259 
00260 void abbdaemon::ABBdaemonClient::syncBuffer(DMABUFFER_HANDLE buffer)
00261 {
00262    if (buffer)
00263       (reinterpret_cast<mprace::DMABuffer*>(buffer))->sync(mprace::DMABuffer::FROMDEVICE);
00264 
00265 }
00266 
00267 void abbdaemon::ABBdaemonClient::unregisterBuffer(DMABUFFER_HANDLE buffer)
00268 {
00269    if (debug) (*debug) << "Unregistering buffer at " << buffer << endl;
00270 
00271    if (buffer)
00272       delete reinterpret_cast<mprace::DMABuffer*>(buffer);
00273 }
00274 
00275 uint32_t abbdaemon::ABBdaemonClient::getFIFOStatus()
00276 {
00277    if (board==0) return 0;
00278 
00279    /* Ignore the lower three bits ("almost full" and "empty" bit) */
00280    return  board->getReg(EVENT_BUFFER_STATUS) & 0xFFFFFFF8;
00281 }
00282 
00283 uint32_t abbdaemon::ABBdaemonClient::getCTLStatus()
00284 {
00285    if (board==0) return 0;
00286 
00287    return board->getReg(CTL_STATUS);
00288 }
00289 
00290 void abbdaemon::ABBdaemonClient::getDesignID(uint32_t *version, uint32_t *major, uint32_t *author, uint32_t *minor)
00291 {
00292    if (board==0) return;
00293 
00294    uint32_t id = board->getReg(DID);
00295 
00296    if (version) *version = (id & 0xFF000000) >> 24;
00297    if (major)   *major   = (id & 0x00FF0000) >> 16;
00298    if (author)  *author  = (id & 0x0000F000) >> 12;
00299    if (minor)   *minor   = (id & 0x00000FFF);
00300 }
00301 
00302 void abbdaemon::ABBdaemonClient::setReg(uint32_t reg, uint32_t value)
00303 {
00304    if (board) board->setReg(reg, value);
00305   
00306 }

Generated on Tue Dec 10 2013 04:52:16 for ROCsoft by  doxygen 1.7.1