45 #include <boost/python.hpp>
46namespace bp = boost::python;
56void rps::SrpV3::setup_python() {
58 bp::class_<rps::SrpV3, rps::SrpV3Ptr, bp::bases<ris::Master, ris::Slave, rim::Slave>, boost::noncopyable>(
61 .def(
"_setHardwareTimeout", &rps::SrpV3::setHardwareTimeout);
62 bp::implicitly_convertible<rps::SrpV3Ptr, ris::MasterPtr>();
63 bp::implicitly_convertible<rps::SrpV3Ptr, ris::SlavePtr>();
64 bp::implicitly_convertible<rps::SrpV3Ptr, rim::SlavePtr>();
69rps::SrpV3::SrpV3() :
ris::Master(),
ris::Slave(),
rim::Slave(4, 4096) {
74rps::SrpV3::~SrpV3() {}
77void rps::SrpV3::setHardwareTimeout(uint8_t val) {
82bool rps::SrpV3::setupHeader(
rim::TransactionPtr tran, uint32_t* header, uint32_t& frameLen,
bool tx) {
89 switch (tran->type()) {
105 header[0] |= (timeout_ << 24 | 0x00000000);
108 header[1] = tran->id();
111 header[2] = tran->address() & 0xFFFFFFFF;
114 header[3] = (tran->address() >> 32) & 0xFFFFFFFF;
117 header[4] = tran->size() - 1;
123 if (tx && doWrite) frameLen += tran->size();
127 frameLen += tran->size() + TailLen;
135 rim::Transaction::iterator tIter;
138 uint32_t header[HeadLen / 4];
142 if ((tran->address() % min()) != 0) {
143 tran->error(
"Transaction address 0x%" PRIx64
" is not aligned to min size %" PRIu32, tran->address(), min());
148 if ((tran->size() % min()) != 0 || tran->size() < min()) {
149 tran->error(
"Transaction size 0x%" PRIx32
" is not aligned to min size %" PRIu32, tran->size(), min());
153 if (tran->size() > max()) {
154 tran->error(
"Transaction size %" PRIu32
" exceeds max size %" PRIu32, tran->size(), max());
159 doWrite = setupHeader(tran, header, frameSize,
true);
162 frame = reqFrame(frameSize,
true);
163 frame->setPayload(frameSize);
168 fIter = frame->begin();
169 tIter = tran->begin();
180 addTransaction(tran);
182 log_->debug(
"Send frame for id=%" PRIu32
", addr 0x%0.8" PRIx64
". Size=%" PRIu32
", type=%" PRIu32,
187 log_->debug(
"Send frame for id=%" PRIu32
", header: 0x%0.8" PRIx32
" 0x%0.8" PRIx32
" 0x%0.8" PRIx32
188 " 0x%0.8" PRIx32
" 0x%0.8" PRIx32,
202 rim::Transaction::iterator tIter;
204 uint32_t header[HeadLen / 4];
205 uint32_t expHeader[HeadLen / 4];
206 uint32_t expFrameLen;
207 uint32_t tail[TailLen / 4];
215 if (frame->getError()) {
216 log_->warning(
"Got errored frame = 0x%" PRIx8, frame->getError());
221 if ((fSize = frame->getPayload()) < (HeadLen + TailLen)) {
222 log_->warning(
"Got undersized frame size = %" PRIu32, fSize);
227 fIter = frame->end() - TailLen;
231 fIter = frame->begin();
236 log_->debug(
"Got frame id=%" PRIu32
", header: 0x%0.8" PRIx32
" 0x%0.8" PRIx32
" 0x%0.8" PRIx32
" 0x%0.8" PRIx32
237 " 0x%0.8" PRIx32
" tail: 0x%0.8" PRIx32,
247 if ((tran = getTransaction(
id)) == NULL) {
248 log_->warning(
"Failed to find transaction id=%" PRIu32,
id);
256 if (tran->expired()) {
257 tran->error(
"Transaction expired: Id=%" PRIu32
258 " (increase root->timeout value if this ID matches a previous timeout message)",
262 tIter = tran->begin();
265 doWrite = setupHeader(tran, expHeader, expFrameLen,
false);
268 if (((header[0] & 0xFFFFC3FF) != expHeader[0]) || (header[1] != expHeader[1]) || (header[2] != expHeader[2]) ||
269 (header[3] != expHeader[3]) || (header[4] != expHeader[4])) {
270 log_->warning(
"Bad header for %" PRIu32,
id);
271 tran->error(
"Received SRPV3 message did not match expected protocol");
277 if (tail[0] & 0x2000)
278 tran->error(
"FPGA register bus lockup detected in hardware. Power cycle required.");
279 else if (tail[0] & 0x0100)
280 tran->error(
"FPGA register bus timeout detected in hardware");
282 tran->error(
"Non zero status message returned on fpga register bus in hardware: 0x%" PRIx32, tail[0]);
283 log_->warning(
"Error detected for ID id=%" PRIu32
", tail=0x%0.8" PRIx32,
id, tail[0]);
288 if ((fSize != expFrameLen) || (header[4] + 1) != tran->size()) {
289 log_->warning(
"Size mismatch id=%" PRIu32
". fsize=%" PRIu32
", exp=%" PRIu32
", tsize=%" PRIu32
296 tran->error(
"Received SRPV3 message had a header size mismatch");
RAII helper that releases the Python GIL for a scope.
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Random-access byte iterator across a Frame payload.
std::shared_ptr< rogue::interfaces::memory::TransactionLock > TransactionLockPtr
Shared pointer alias for TransactionLock.
static const uint32_t Write
Memory write transaction type.
std::shared_ptr< rogue::interfaces::memory::Transaction > TransactionPtr
Shared pointer alias for Transaction.
static const uint32_t Post
Memory posted write transaction type.
static void fromFrame(rogue::interfaces::stream::FrameIterator &iter, uint32_t size, void *dst)
Copies bytes from a frame iterator to a destination pointer.
std::shared_ptr< rogue::interfaces::stream::Frame > FramePtr
Shared pointer alias for Frame.
static void toFrame(rogue::interfaces::stream::FrameIterator &iter, uint32_t size, void *src)
Copies bytes from a source pointer into a frame iterator.
std::shared_ptr< rogue::interfaces::stream::FrameLock > FrameLockPtr
Shared pointer alias for FrameLock.
std::shared_ptr< rogue::protocols::srp::SrpV3 > SrpV3Ptr