summaryrefslogtreecommitdiff
path: root/usrp2/host
diff options
context:
space:
mode:
authorjcorgan2008-12-27 21:09:26 +0000
committerjcorgan2008-12-27 21:09:26 +0000
commit297479844e3d9a6eea54fa69147e6a20c0bfc412 (patch)
tree786591a2e3c8aa77d8149630a6a5d00974585af7 /usrp2/host
parenta09700c26a39ebddbeb56b5ecddedf50f0cc7ac4 (diff)
downloadgnuradio-297479844e3d9a6eea54fa69147e6a20c0bfc412.tar.gz
gnuradio-297479844e3d9a6eea54fa69147e6a20c0bfc412.tar.bz2
gnuradio-297479844e3d9a6eea54fa69147e6a20c0bfc412.zip
Implements USRP2 peek() command, allowing arbitrary reads from the internal
Wishbone bus. Minor fix for USRP2 sync_to_pps() (uses correct packet type.) Example: >>> from gnuradio import usrp2 >>> u = usrp2.source_32fc() >>> u.peek(0x1234, 4) # Read four bytes at offset 0x1234 (code) (185, 244, 253, 164) >>> The return value will be zero length upon error. The read address must be 32-bit aligned, and only the lower 16 bits are significant. The length must be an integral multiple of 4 bytes. There is currently a read limit of 176 bytes per read; to change requires some additional firmware changes to allocate a larger reply packet. WARNING: Trying to read from memory locations not serviced by RAM or by a Wishbone peripheral may result in a hang requiring a USRP2 power cycle. The USRP2 internal memory map is documented in usrp2/firmware/lib/memory_map.h. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10172 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp2/host')
-rw-r--r--usrp2/host/include/usrp2/usrp2.h15
-rw-r--r--usrp2/host/lib/control.h12
-rw-r--r--usrp2/host/lib/usrp2.cc6
-rw-r--r--usrp2/host/lib/usrp2_impl.cc56
-rw-r--r--usrp2/host/lib/usrp2_impl.h1
5 files changed, 82 insertions, 8 deletions
diff --git a/usrp2/host/include/usrp2/usrp2.h b/usrp2/host/include/usrp2/usrp2.h
index 4fa9da1ee..e942bb579 100644
--- a/usrp2/host/include/usrp2/usrp2.h
+++ b/usrp2/host/include/usrp2/usrp2.h
@@ -361,6 +361,21 @@ namespace usrp2 {
*/
bool sync_to_pps();
+ /*!
+ * Read memory from Wishbone bus
+ *
+ * \param addr 32-bit aligned address. Only the lower 16-bits are significant.
+ * \param len Number of bytes to read, must be positive and multiple of 4.
+ *
+ * \returns Vector of 8-bit read values
+ *
+ * WARNING: Attempts to read memory from addresses that do not correspond to RAM or
+ * memory-mapped peripherals may cause the USRP2 to hang, requiring a power cycle.
+ *
+ */
+ std::vector<uint8_t> peek(uint32_t addr, uint32_t len);
+
+
#if 0 // not yet implemented
/*!
* \brief Write EEPROM on motherboard or any daughterboard.
diff --git a/usrp2/host/lib/control.h b/usrp2/host/lib/control.h
index fe30b3f74..774ca85f6 100644
--- a/usrp2/host/lib/control.h
+++ b/usrp2/host/lib/control.h
@@ -23,6 +23,13 @@
#include <usrp2_eth_packet.h>
namespace usrp2 {
+
+ struct op_generic_cmd {
+ u2_eth_packet_t h;
+ op_generic_t op;
+ op_generic_t eop;
+ };
+
/*!
* OP_CONFIG_RX_V2 command packet
*/
@@ -73,6 +80,11 @@ namespace usrp2 {
op_generic_t eop;
};
+ struct op_peek_cmd {
+ u2_eth_packet_t h;
+ op_peek_t op;
+ op_generic_t eop;
+ };
/*!
* Control mechanism to allow API calls to block waiting for reply packets
diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc
index ecfc0b30a..136062d08 100644
--- a/usrp2/host/lib/usrp2.cc
+++ b/usrp2/host/lib/usrp2.cc
@@ -395,6 +395,12 @@ namespace usrp2 {
return d_impl->sync_to_pps();
}
+ std::vector<uint8_t>
+ usrp2::peek(uint32_t addr, uint32_t len)
+ {
+ return d_impl->peek(addr, len);
+ }
+
} // namespace usrp2
diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc
index 24e6d7e73..d7769a842 100644
--- a/usrp2/host/lib/usrp2_impl.cc
+++ b/usrp2/host/lib/usrp2_impl.cc
@@ -72,12 +72,9 @@ namespace usrp2 {
case OP_DBOARD_INFO: return "OP_DBOARD_INFO";
case OP_DBOARD_INFO_REPLY: return "OP_DBOARD_INFO_REPLY";
case OP_SYNC_TO_PPS: return "OP_SYNC_TO_PPS";
-#if 0
- case OP_WRITE_REG: return "OP_WRITE_REG";
- case OP_WRITE_REG_MASKED: return "OP_WRITE_REG_MASKED";
- case OP_READ_REG: return "OP_READ_REG";
- case OP_READ_REG_REPLY: return "OP_READ_REG_REPLY";
-#endif
+ case OP_PEEK: return "OP_PEEK";
+ case OP_PEEK_REPLY: return "OP_PEEK_REPLY";
+
default:
char buf[64];
snprintf(buf, sizeof(buf), "<unknown opcode: %d>", opcode);
@@ -1024,8 +1021,8 @@ namespace usrp2 {
bool
usrp2::impl::sync_to_pps()
{
- op_config_mimo_cmd cmd;
- op_generic_t reply;
+ op_generic_cmd cmd;
+ op_generic_t reply;
memset(&cmd, 0, sizeof(cmd));
init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
@@ -1042,4 +1039,47 @@ namespace usrp2 {
return ntohx(reply.ok) == 1;
}
+ std::vector<uint8_t>
+ usrp2::impl::peek(uint32_t addr, uint32_t len)
+ {
+ std::vector<uint8_t> result; // zero sized on error return
+ // fprintf(stderr, "usrp2::peek: addr=%08X len=%u\n", addr, len);
+
+ if (addr % 4 != 0) {
+ fprintf(stderr, "usrp2::peek: addr (=%08X) must be 32-bit word aligned\n", addr);
+ return result;
+ }
+
+ if (len < 4 || len % 4 != 0) {
+ fprintf(stderr, "usrp2::peek: len (=%u) must be an integral multiple of 4\n", len);
+ return result;
+ }
+
+ op_peek_cmd cmd;
+ op_generic_t *reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_PEEK;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ cmd.op.addr = htonl(addr);
+ cmd.op.bytes = htonl(len);
+
+ reply = (op_generic_t *)malloc(sizeof(*reply)+len);
+ pending_reply p(cmd.op.rid, reply, sizeof(*reply)+len);
+ if (transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) {
+ uint32_t bytes = reply->len-sizeof(*reply);
+ uint8_t *data = (uint8_t *)(reply)+sizeof(*reply);
+ for (unsigned int i = 0; i < bytes; i++)
+ result.push_back(data[i]);
+ }
+
+ free(reply);
+ return result;
+ }
+
} // namespace usrp2
diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h
index f5030f541..d9701287e 100644
--- a/usrp2/host/lib/usrp2_impl.h
+++ b/usrp2/host/lib/usrp2_impl.h
@@ -174,6 +174,7 @@ namespace usrp2 {
bool burn_mac_addr(const std::string &new_addr);
bool sync_to_pps();
+ std::vector<uint8_t> peek(uint32_t addr, uint32_t len);
};
} // namespace usrp2