summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-09-09 13:39:52 -0700
committerJosh Blum <josh@joshknows.com>2011-09-28 10:32:05 -0700
commit25494489bf8b7c60875ea355d29323bcfffd604b (patch)
treebbb533238db6fc24d807670c2adf23d59de9160a /host/lib
parent18a3f03c06c65d79e5c4b7ac1076077c4b9fd8ff (diff)
downloaduhd-25494489bf8b7c60875ea355d29323bcfffd604b.tar.gz
uhd-25494489bf8b7c60875ea355d29323bcfffd604b.tar.bz2
uhd-25494489bf8b7c60875ea355d29323bcfffd604b.zip
usrp2: uart/udp work in host and fw, working
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/transport/udp_simple.cpp46
-rw-r--r--host/lib/usrp/gps_ctrl.cpp32
-rw-r--r--host/lib/usrp/usrp2/fw_common.h13
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp60
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.hpp9
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp9
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp2
7 files changed, 78 insertions, 93 deletions
diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp
index ed778fbf4..bc1bdaf2f 100644
--- a/host/lib/transport/udp_simple.cpp
+++ b/host/lib/transport/udp_simple.cpp
@@ -81,3 +81,49 @@ udp_simple::sptr udp_simple::make_broadcast(
){
return sptr(new udp_simple_impl(addr, port, true, false /* bcast, no connect */));
}
+
+/***********************************************************************
+ * Simple UART over UDP
+ **********************************************************************/
+#include <boost/thread/thread.hpp>
+class udp_simple_uart_impl : public uhd::uart_iface{
+public:
+ udp_simple_uart_impl(udp_simple::sptr udp){
+ _udp = udp;
+ _len = 0;
+ _off = 0;
+ this->write_uart(""); //send an empty packet to init
+ }
+
+ void write_uart(const std::string &buf){
+ _udp->send(asio::buffer(buf));
+ }
+
+ std::string read_uart(double timeout){
+ std::string line;
+ const boost::system_time exit_time = boost::get_system_time() + boost::posix_time::milliseconds(long(timeout*1000));
+ do{
+ //drain anything in current buffer
+ while (_off < _len){
+ const char ch = _buf[_off]; _off++;
+ line += std::string(1, ch);
+ if (ch == '\n' or ch == '\r') return line;
+ }
+
+ //recv a new packet into the buffer
+ _len = _udp->recv(asio::buffer(_buf), std::max((exit_time - boost::get_system_time()).total_milliseconds()/1000., 0.0));
+ _off = 0;
+
+ } while (_len != 0);
+ return line;
+ }
+
+private:
+ udp_simple::sptr _udp;
+ size_t _len, _off;
+ boost::uint8_t _buf[udp_simple::mtu];
+};
+
+uhd::uart_iface::sptr udp_simple::make_uart(sptr udp){
+ return uart_iface::sptr(new udp_simple_uart_impl(udp));
+}
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index 342b0e2fe..96cb76ffc 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -40,19 +40,18 @@ using namespace boost::this_thread;
class gps_ctrl_impl : public gps_ctrl{
public:
- gps_ctrl_impl(gps_send_fn_t send, gps_recv_fn_t recv){
- _send = send;
- _recv = recv;
+ gps_ctrl_impl(uart_iface::sptr uart){
+ _uart = uart;
std::string reply;
bool i_heard_some_nmea = false, i_heard_something_weird = false;
gps_type = GPS_TYPE_NONE;
//first we look for a Jackson Labs Firefly (since that's what we provide...)
- _recv(); //get whatever junk is in the rx buffer right now, and throw it away
+ _flush(); //get whatever junk is in the rx buffer right now, and throw it away
_send("HAAAY GUYYYYS\n"); //to elicit a response from the Firefly
- //wait for _send(...) to return
+ //wait for _send(...) to return
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
//then we loop until we either timeout, or until we get a response that indicates we're a JL device
@@ -155,7 +154,7 @@ private:
return std::string();
}
- while(_recv().size() != 0) sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
+ _flush(); //flush all input before waiting for a message
int timeout = GPS_TIMEOUT_TRIES;
while(timeout--) {
@@ -242,8 +241,21 @@ private:
return false;
}
- gps_send_fn_t _send;
- gps_recv_fn_t _recv;
+ uart_iface::sptr _uart;
+
+ void _flush(void){
+ while (not _uart->read_uart(0.0).empty()){
+ //NOP
+ }
+ }
+
+ std::string _recv(void){
+ return _uart->read_uart(GPS_TIMEOUT_DELAY_MS/1000.);
+ }
+
+ void _send(const std::string &buf){
+ return _uart->write_uart(buf);
+ }
enum {
GPS_TYPE_JACKSON_LABS,
@@ -259,6 +271,6 @@ private:
/***********************************************************************
* Public make function for the GPS control
**********************************************************************/
-gps_ctrl::sptr gps_ctrl::make(gps_send_fn_t send, gps_recv_fn_t recv){
- return sptr(new gps_ctrl_impl(send, recv));
+gps_ctrl::sptr gps_ctrl::make(uart_iface::sptr uart){
+ return sptr(new gps_ctrl_impl(uart));
}
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 2da4e1e48..7ad06f33f 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -31,8 +31,8 @@ extern "C" {
//fpga and firmware compatibility numbers
#define USRP2_FPGA_COMPAT_NUM 7
-#define USRP2_FW_COMPAT_NUM 10
-#define USRP2_FW_VER_MINOR 4
+#define USRP2_FW_COMPAT_NUM 11
+#define USRP2_FW_VER_MINOR 0
//used to differentiate control packets over data port
#define USRP2_INVALID_VRT_HEADER 0
@@ -45,6 +45,7 @@ extern "C" {
#define USRP2_UDP_TX_DSP0_PORT 49157
#define USRP2_UDP_RX_DSP1_PORT 49158
#define USRP2_UDP_UART_BASE_PORT 49170
+#define USRP2_UDP_UART_GPS_PORT 49172
// Map for virtual firmware regs (not very big so we can keep it here for now)
#define U2_FW_REG_LOCK_TIME 0
@@ -90,9 +91,6 @@ typedef enum{
USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO = 'u',
USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE = 'U',
- USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO = 'v',
- USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE = 'V',
-
USRP2_CTRL_ID_HOLLER_AT_ME_BRO = 'l',
USRP2_CTRL_ID_HOLLER_BACK_DUDE = 'L',
@@ -144,11 +142,6 @@ typedef struct{
uint8_t action;
} reg_args;
struct {
- uint8_t dev;
- uint8_t bytes;
- uint8_t data[20];
- } uart_args;
- struct {
uint32_t len;
} echo_args;
} data;
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index d91dd0e40..c1e92e7d4 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -245,66 +245,6 @@ public:
}
/***********************************************************************
- * UART
- **********************************************************************/
- void write_uart(boost::uint8_t dev, const std::string &buf){
- //first tokenize the string into 20-byte substrings
- boost::offset_separator f(20, 20, true, true);
- boost::tokenizer<boost::offset_separator> tok(buf, f);
- std::vector<std::string> queue(tok.begin(), tok.end());
-
- BOOST_FOREACH(std::string item, queue) {
- //setup the out data
- usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
- out_data.id = htonl(USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO);
- out_data.data.uart_args.dev = dev;
- out_data.data.uart_args.bytes = item.size();
-
- //limitation of uart transaction size
- UHD_ASSERT_THROW(item.size() <= sizeof(out_data.data.uart_args.data));
-
- //copy in the data
- std::copy(item.begin(), item.end(), out_data.data.uart_args.data);
-
- //send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_UART);
- UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE);
- }
- }
-
- std::string read_uart(boost::uint8_t dev){
- int readlen = 20;
- std::string result;
- while(readlen == 20) { //while we keep receiving full packets
- //setup the out data
- usrp2_ctrl_data_t out_data = usrp2_ctrl_data_t();
- out_data.id = htonl(USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO);
- out_data.data.uart_args.dev = dev;
- out_data.data.uart_args.bytes = 20;
-
- //limitation of uart transaction size
- //UHD_ASSERT_THROW(num_bytes <= sizeof(out_data.data.uart_args.data));
-
- //send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_UART);
- UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE);
- readlen = in_data.data.uart_args.bytes;
-
- //copy out the data
- result += std::string((const char *)in_data.data.uart_args.data, (size_t)readlen);
- }
- return result;
- }
-
- gps_send_fn_t get_gps_write_fn(void) {
- return boost::bind(&usrp2_iface_impl::write_uart, this, 2, _1); //2 is the GPS UART port on USRP2
- }
-
- gps_recv_fn_t get_gps_read_fn(void) {
- return boost::bind(&usrp2_iface_impl::read_uart, this, 2); //2 is the GPS UART port on USRP2
- }
-
-/***********************************************************************
* Send/Recv over control
**********************************************************************/
usrp2_ctrl_data_t ctrl_send_and_recv(
diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp
index b3c3ef4a2..9aa1a16aa 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.hpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.hpp
@@ -28,16 +28,12 @@
#include "wb_iface.hpp"
#include <string>
-//TODO: kill this crap when you have the top level GPS include file
-typedef boost::function<void(std::string)> gps_send_fn_t;
-typedef boost::function<std::string(void)> gps_recv_fn_t;
-
/*!
* The usrp2 interface class:
* Provides a set of functions to implementation layer.
* Including spi, peek, poke, control...
*/
-class usrp2_iface : public wb_iface, public uhd::spi_iface, public uhd::i2c_iface, public uhd::uart_iface{
+class usrp2_iface : public wb_iface, public uhd::spi_iface, public uhd::i2c_iface{
public:
typedef boost::shared_ptr<usrp2_iface> sptr;
/*!
@@ -47,9 +43,6 @@ public:
*/
static sptr make(uhd::transport::udp_simple::sptr ctrl_transport);
- virtual gps_recv_fn_t get_gps_read_fn(void) = 0;
- virtual gps_send_fn_t get_gps_write_fn(void) = 0;
-
//! The list of possible revision types
enum rev_type {
USRP2_REV3 = 3,
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 03a9d09fe..47aec08d5 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -438,10 +438,9 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create gpsdo control objects
////////////////////////////////////////////////////////////////
if (_mbc[mb].iface->mb_eeprom["gpsdo"] == "internal"){
- _mbc[mb].gps = gps_ctrl::make(
- _mbc[mb].iface->get_gps_write_fn(),
- _mbc[mb].iface->get_gps_read_fn()
- );
+ _mbc[mb].gps = gps_ctrl::make(udp_simple::make_uart(udp_simple::make_connected(
+ addr, BOOST_STRINGIZE(USRP2_UDP_UART_GPS_PORT)
+ )));
if(_mbc[mb].gps->gps_detected()) {
BOOST_FOREACH(const std::string &name, _mbc[mb].gps->get_sensors()){
_tree->create<sensor_value_t>(mb_path / "sensors" / name)
@@ -624,8 +623,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
//GPS installed: use external ref, time, and init time spec
if (_mbc[mb].gps.get() and _mbc[mb].gps->gps_detected()){
+ UHD_MSG(status) << "Setting references to the internal GPSDO" << std::endl;
_tree->access<std::string>(root / "time_source/value").set("external");
_tree->access<std::string>(root / "clock_source/value").set("external");
+ UHD_MSG(status) << "Initializing time to the internal GPSDO" << std::endl;
_mbc[mb].time64->set_time_next_pps(time_spec_t(time_t(_mbc[mb].gps->get_sensor("gps_time").to_int()+1)));
}
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 28cbaf479..6f133f411 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -93,7 +93,7 @@ private:
usrp2_iface::sptr iface;
usrp2_clock_ctrl::sptr clock;
usrp2_codec_ctrl::sptr codec;
- gps_ctrl::sptr gps;
+ uhd::gps_ctrl::sptr gps;
rx_frontend_core_200::sptr rx_fe;
tx_frontend_core_200::sptr tx_fe;
std::vector<rx_dsp_core_200::sptr> rx_dsps;