vector<byte> *OOIEEPROMProtocol::readEEPROMSlot(const Bus &bus, int slot) throw (ProtocolException) { ByteVector *bv = NULL; Data *result = NULL; ReadEEPROMSlotExchange xchange(slot); TransferHelper *helper = bus.getHelper(xchange.getHints()); if(NULL == helper) { string error("Failed to find a helper to bridge given protocol and bus."); throw ProtocolBusMismatchException(error); } result = xchange.transfer(helper); if(NULL == result) { string error("Expected Transfer::transfer to produce a non-null result " "containing raw EEPROM data. Without this data, it is not possible to " "generate a valid EEPROM slot value."); throw ProtocolException(error); } bv = static_cast<ByteVector *>(result); // strip off leading two bytes (echoed request) vector<byte> raw = bv->getByteVector(); vector<byte> *retval = new vector<byte>(raw.size() - 2); memcpy(&((*retval)[0]), &(raw[2]), retval->size()); delete result; /* a.k.a. bv */ return retval; }
vector<float> *OOIIrradCalProtocol::readIrradCal(const Bus &bus) throw (ProtocolException) { TransferHelper *helper; OOIReadIrradCalExchange readCalExchange(this->numberOfPixels); helper = bus.getHelper(readCalExchange.getHints()); if (NULL == helper) { string error("Failed to find a helper to bridge given protocol and bus."); throw ProtocolBusMismatchException(error); } /* This transfer() may cause a ProtocolException to be thrown. */ Data *result = readCalExchange.transfer(helper); if (NULL == result) { string error("Expected Transfer::transfer to produce a non-null result " "containing calibration data. Without this data, it is not possible to " "generate a calibration array."); throw ProtocolException(error); } /* FIXME: this cast is known to be safe for now, but this needs * to do some sort of check to make sure the cast is valid. */ ByteVector *bv = static_cast<ByteVector *>(result); vector<byte> raw = bv->getByteVector(); vector<float> *retval = new vector<float>; for(unsigned int i = 0; i < raw.size(); i += 4) { float value; unsigned int *fptr = (unsigned int *)&value; /* The convention here is MSB first */ *fptr = ((raw[i] & 0x00FF) << 24) | ((raw[i + 1] & 0x00FF) << 16) | ((raw[i + 2] & 0x00FF) << 8) | ((raw[i + 3] & 0x00FF)); retval->push_back(value); } delete result; return retval; }
unsigned int FPGARegisterProtocol::readRegister(const Bus &bus, byte address) throw (ProtocolException) { unsigned int retval = 0; FPGARegisterReadExchange exchange(address); TransferHelper *helper = bus.getHelper(exchange.getHints()); if(NULL == helper) { string error("Failed to find a helper to bridge given protocol and bus."); throw ProtocolBusMismatchException(error); } Data* result = exchange.transfer(helper); if(NULL == result) { string error("Expected non-NULL result from FPGARegisterReadExchange"); throw ProtocolException(error); } ByteVector *bv = dynamic_cast<ByteVector *>(result); if(NULL == bv) { throw ProtocolException(string("Expected ByteVector from FPGARegisterReadExchange")); } vector<byte> byteVec = bv->getByteVector(); if(3 != byteVec.size()) { throw ProtocolException(string("Expected 3 bytes from FPGARegisterReadExchange")); } // Response is 3 bytes (address echo, LSB, MSB) // TODO: this will need to be updated when we have devices with 32-bit registers retval = (unsigned int) (byteVec[1] | ((unsigned int) byteVec[2] << 8)); delete result; return retval; }
Data *OOIReadIrradCalExchange::transfer(TransferHelper *helper) throw (ProtocolException) { Data *xfer; ByteVector *output = new ByteVector(); vector<Transfer *>::iterator iter = this->transfers.begin(); /* Number of calibration bytes that will be read */ int bytesLeft = this->numberOfPixels * sizeof(float); /* Iterate over all stored transfers and delegate to the helper to * move the data. */ for(iter = this->transfers.begin(); iter != this->transfers.end(); iter++) { /* Note that this may throw a ProtocolException which will not be caught here. */ /* Either send request for data, or obtain data. * xfer will be NULL if request being issued. * data is returned as ByteVector type object if data being returned. */ xfer = (*iter)->transfer(helper); if(NULL != xfer) { /* transfer block of 60 bytes from xfer to output */ for( unsigned int i = 0; i < ((ByteVector*)xfer)->getByteVector().size() && bytesLeft > 0; i++, bytesLeft--) { /* FIXME: can this be done more efficiently using a memcpy()? */ output->getByteVector().push_back( ((ByteVector*)xfer)->getByteVector()[i]); } delete xfer; /* clear for next iteration */ } } /* return concatenated data as ByteVector */ return output; }