aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/b100/b100_ctrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/b100/b100_ctrl.cpp')
-rw-r--r--host/lib/usrp/b100/b100_ctrl.cpp74
1 files changed, 53 insertions, 21 deletions
diff --git a/host/lib/usrp/b100/b100_ctrl.cpp b/host/lib/usrp/b100/b100_ctrl.cpp
index 6d415facc..3f6d0d86e 100644
--- a/host/lib/usrp/b100/b100_ctrl.cpp
+++ b/host/lib/usrp/b100/b100_ctrl.cpp
@@ -36,7 +36,7 @@ bool b100_ctrl_debug = false;
class b100_ctrl_impl : public b100_ctrl {
public:
- b100_ctrl_impl(uhd::transport::usb_zero_copy::sptr ctrl_transport) :
+ b100_ctrl_impl(uhd::transport::zero_copy_if::sptr ctrl_transport) :
sync_ctrl_fifo(2),
async_msg_fifo(100),
_ctrl_transport(ctrl_transport),
@@ -46,29 +46,61 @@ public:
viking_marauders.create_thread(boost::bind(&b100_ctrl_impl::viking_marauder_loop, this, boost::ref(spawn_barrier)));
spawn_barrier.wait();
}
-
+
int write(boost::uint32_t addr, const ctrl_data_t &data);
ctrl_data_t read(boost::uint32_t addr, size_t len);
-
+
~b100_ctrl_impl(void) {
viking_marauders.interrupt_all();
viking_marauders.join_all();
}
-
+
bool get_ctrl_data(ctrl_data_t &pkt_data, double timeout);
bool recv_async_msg(uhd::async_metadata_t &async_metadata, double timeout);
-
+
+ void poke32(wb_addr_type addr, boost::uint32_t data){
+ boost::mutex::scoped_lock lock(_ctrl_mutex);
+
+ ctrl_data_t words(2);
+ words[0] = data & 0x0000FFFF;
+ words[1] = data >> 16;
+ this->write(addr, words);
+ }
+
+ boost::uint32_t peek32(wb_addr_type addr){
+ boost::mutex::scoped_lock lock(_ctrl_mutex);
+
+ ctrl_data_t words = this->read(addr, 2);
+ return boost::uint32_t((boost::uint32_t(words[1]) << 16) | words[0]);
+ }
+
+ void poke16(wb_addr_type addr, boost::uint16_t data){
+ boost::mutex::scoped_lock lock(_ctrl_mutex);
+
+ ctrl_data_t words(1);
+ words[0] = data;
+ this->write(addr, words);
+ }
+
+ boost::uint16_t peek16(wb_addr_type addr){
+ boost::mutex::scoped_lock lock(_ctrl_mutex);
+
+ ctrl_data_t words = this->read(addr, 1);
+ return boost::uint16_t(words[0]);
+ }
+
private:
int send_pkt(boost::uint16_t *cmd);
-
+
//änd hërë wë gö ä-Vïkïng för äsynchronous control packets
void viking_marauder_loop(boost::barrier &);
bounded_buffer<ctrl_data_t> sync_ctrl_fifo;
bounded_buffer<async_metadata_t> async_msg_fifo;
boost::thread_group viking_marauders;
-
- uhd::transport::usb_zero_copy::sptr _ctrl_transport;
+
+ uhd::transport::zero_copy_if::sptr _ctrl_transport;
boost::uint8_t _seq;
+ boost::mutex _ctrl_mutex;
};
/***********************************************************************
@@ -86,7 +118,7 @@ void pack_ctrl_pkt(boost::uint16_t *pkt_buff,
pkt_buff[1] = pkt.pkt_meta.len;
pkt_buff[2] = (pkt.pkt_meta.addr & 0x00000FFF);
pkt_buff[3] = 0x0000; //address high bits always 0 on this device
-
+
for(size_t i = 0; i < pkt.data.size(); i++) {
pkt_buff[4+i] = pkt.data[i];
}
@@ -99,7 +131,7 @@ void unpack_ctrl_pkt(const boost::uint16_t *pkt_buff,
pkt.pkt_meta.len = pkt_buff[1];
pkt.pkt_meta.callbacks = 0; //callbacks aren't implemented yet
pkt.pkt_meta.addr = pkt_buff[2] | boost::uint32_t(pkt_buff[3] << 16);
-
+
//let's check this so we don't go pushing 64K of crap onto the pkt
if(pkt.pkt_meta.len > CTRL_PACKET_DATA_LENGTH) {
throw uhd::runtime_error("Received control packet too long");
@@ -113,7 +145,7 @@ int b100_ctrl_impl::send_pkt(boost::uint16_t *cmd) {
if(!sbuf.get()) {
throw uhd::runtime_error("Control channel send error");
}
-
+
//FIXME there's a better way to do this
for(size_t i = 0; i < (CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)); i++) {
sbuf->cast<boost::uint16_t *>()[i] = cmd[i];
@@ -132,7 +164,7 @@ int b100_ctrl_impl::write(boost::uint32_t addr, const ctrl_data_t &data) {
pkt.pkt_meta.len = pkt.data.size();
pkt.pkt_meta.addr = addr;
boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)];
-
+
pack_ctrl_pkt(pkt_buff, pkt);
size_t result = send_pkt(pkt_buff);
return result;
@@ -151,7 +183,7 @@ ctrl_data_t b100_ctrl_impl::read(boost::uint32_t addr, size_t len) {
pack_ctrl_pkt(pkt_buff, pkt);
send_pkt(pkt_buff);
-
+
//loop around waiting for the response to appear
while(!get_ctrl_data(pkt.data, 0.05));
@@ -168,24 +200,24 @@ ctrl_data_t b100_ctrl_impl::read(boost::uint32_t addr, size_t len) {
void b100_ctrl_impl::viking_marauder_loop(boost::barrier &spawn_barrier) {
spawn_barrier.wait();
set_thread_priority_safe();
-
+
while (not boost::this_thread::interruption_requested()){
managed_recv_buffer::sptr rbuf = _ctrl_transport->get_recv_buff();
if(!rbuf.get()) continue; //that's ok, there are plenty of villages to pillage!
const boost::uint16_t *pkt_buf = rbuf->cast<const boost::uint16_t *>();
-
+
if(pkt_buf[0] >> 8 == CTRL_PACKET_HEADER_MAGIC) {
//so it's got a control packet header, let's parse it.
ctrl_pkt_t pkt;
unpack_ctrl_pkt(pkt_buf, pkt);
-
+
if(pkt.pkt_meta.seq != boost::uint8_t(_seq - 1)) {
throw uhd::runtime_error("Sequence error on control channel");
}
if(pkt.pkt_meta.len > (CTRL_PACKET_LENGTH - CTRL_PACKET_HEADER_LENGTH)) {
throw uhd::runtime_error("Control channel packet length too long");
}
-
+
//push it onto the queue
sync_ctrl_fifo.push_with_wait(pkt.data);
} else { //it's an async status pkt
@@ -194,8 +226,8 @@ void b100_ctrl_impl::viking_marauder_loop(boost::barrier &spawn_barrier) {
if_packet_info.num_packet_words32 = rbuf->size()/sizeof(boost::uint32_t);
const boost::uint32_t *vrt_hdr = rbuf->cast<const boost::uint32_t *>();
vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info);
-
- if( if_packet_info.sid == B100_ASYNC_SID
+
+ if( if_packet_info.sid == B100_TX_ASYNC_SID
and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){
//fill in the async metadata
async_metadata_t metadata;
@@ -207,7 +239,7 @@ void b100_ctrl_impl::viking_marauder_loop(boost::barrier &spawn_barrier) {
metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));
async_msg_fifo.push_with_pop_on_full(metadata);
if (metadata.event_code &
- ( async_metadata_t::EVENT_CODE_UNDERFLOW
+ ( async_metadata_t::EVENT_CODE_UNDERFLOW
| async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET)
) UHD_MSG(fastpath) << "U";
else if (metadata.event_code &
@@ -234,6 +266,6 @@ bool b100_ctrl_impl::recv_async_msg(uhd::async_metadata_t &async_metadata, doubl
/***********************************************************************
* Public make function for b100_ctrl interface
**********************************************************************/
-b100_ctrl::sptr b100_ctrl::make(uhd::transport::usb_zero_copy::sptr ctrl_transport){
+b100_ctrl::sptr b100_ctrl::make(uhd::transport::zero_copy_if::sptr ctrl_transport){
return sptr(new b100_ctrl_impl(ctrl_transport));
}