diff options
author | Josh Blum <josh@joshknows.com> | 2011-09-09 13:39:52 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-09-28 10:32:05 -0700 |
commit | 25494489bf8b7c60875ea355d29323bcfffd604b (patch) | |
tree | bbb533238db6fc24d807670c2adf23d59de9160a /host/lib | |
parent | 18a3f03c06c65d79e5c4b7ac1076077c4b9fd8ff (diff) | |
download | uhd-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.cpp | 46 | ||||
-rw-r--r-- | host/lib/usrp/gps_ctrl.cpp | 32 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 13 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 60 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.hpp | 9 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 9 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 2 |
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; |