diff options
author | Nick Foster <nick@nerdnetworks.org> | 2010-08-13 11:34:07 -0700 |
---|---|---|
committer | Nick Foster <nick@nerdnetworks.org> | 2010-08-13 11:34:07 -0700 |
commit | f09d9820ed40371f552d3a910bc2d8170d290653 (patch) | |
tree | d0a2d1b5d807aea51717be881cbfd27fbd45fe20 | |
parent | 3fe2744e7aef9f6989b161be3af63a24392ed18a (diff) | |
download | uhd-f09d9820ed40371f552d3a910bc2d8170d290653.tar.gz uhd-f09d9820ed40371f552d3a910bc2d8170d290653.tar.bz2 uhd-f09d9820ed40371f552d3a910bc2d8170d290653.zip |
first stab at a GPS driver in gps_ctrl.cpp. not the most expandable thing in the world but there's only so many GPS interfaces out there.
-rw-r--r-- | firmware/microblaze/apps/txrx_uhd.c | 3 | ||||
-rw-r--r-- | firmware/microblaze/lib/hal_uart.c | 7 | ||||
-rw-r--r-- | firmware/microblaze/lib/hal_uart.h | 1 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/CMakeLists.txt | 2 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/gps_ctrl.cpp | 140 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/gps_ctrl.hpp | 53 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 7 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 2 |
8 files changed, 209 insertions, 6 deletions
diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 2065830ff..9fe17e262 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -324,6 +324,9 @@ void handle_udp_ctrl_packet( case USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO:{ int num_bytes = ctrl_data_in->data.uart_args.bytes; if(num_bytes > 20) num_bytes = 20; + //before we write to the UART, we flush the receive buffer + //this assumes that we're interested in the reply + hal_uart_rx_flush(ctrl_data_in->data.uart_args.dev); fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE; ctrl_data_out.data.uart_args.bytes = num_bytes; diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index a8344daf5..8f7f83a68 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -101,3 +101,10 @@ hal_uart_getc(hal_uart_name_t u) return uart_regs[u].rxchar; } +int hal_uart_rx_flush(hal_uart_name_t u) +{ + char x; + while(uart_regs[u].rxlevel) x = uart_regs[u].rxchar; + return x; +} + diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index 81f4a6777..051dffe92 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -82,5 +82,6 @@ void hal_uart_putc_nowait(hal_uart_name_t u, int ch); */ int hal_uart_getc(hal_uart_name_t u); +int hal_uart_rx_flush(hal_uart_name_t u); #endif /* INCLUDED_HAL_UART_H */ diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index b4a90a6ba..47d74cec8 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -26,6 +26,8 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp diff --git a/host/lib/usrp/usrp2/gps_ctrl.cpp b/host/lib/usrp/usrp2/gps_ctrl.cpp new file mode 100644 index 000000000..5c015be14 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.cpp @@ -0,0 +1,140 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "gps_ctrl.hpp" +#include <uhd/utils/assert.hpp> +#include <boost/cstdint.hpp> +#include <string> +#include <boost/date_time/posix_time/posix_time.hpp> + +using namespace uhd; +using namespace boost::gregorian; +using namespace boost::posix_time; + +/*! + * A usrp2 GPS control for Jackson Labs devices + */ + +//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers), NMEA support, better autodetection +class usrp2_gps_ctrl_impl : public usrp2_gps_ctrl{ +public: + usrp2_gps_ctrl_impl(usrp2_iface::sptr iface){ + _iface = iface; + //do init here + //so the Jackson Labs Firefly (and Fury) don't acknowledge successful commands -- only invalid ones. + //first we test to see if there's a Firefly/Fury connected by sending an invalid packet and listening for the response + + std::string reply; + + //TODO: try multiple baud rates (many GPS's are set up for 4800bps, you're fixed at 115200bps 8N1 right now) + //you have to poke registers in order to set baud rate, there's no dude/bro interface for it + _iface->write_uart(GPS_UART, "HAAAY GUYYYYS\n"); + try { + reply = _iface->read_uart(GPS_UART, 20); + } catch (std::runtime_error err) { + if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that + else { //we don't actually have a GPS installed + gps_type = GPS_TYPE_NONE; + } + } + + if(reply == "Command Error") gps_type = GPS_TYPE_JACKSON_LABS; + else gps_type = GPS_TYPE_NONE; //we'll add NMEA support later + + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + //issue some setup stuff so it quits spewing data out when not asked to + //none of these should issue replies so we don't bother looking for it + _iface->write_uart(GPS_UART, "SYST:COMM:SER:"); + _iface->write_uart(GPS_UART, "ECHO OFF\n"); //we split lines before 20 chars right now -- TODO: fix driver to split writes/reads for you + _iface->write_uart(GPS_UART, "SYST:COMM:SER:"); + _iface->write_uart(GPS_UART, "PRO OFF\n"); + _iface->write_uart(GPS_UART, "GPS:GPGGA 0\n"); + _iface->write_uart(GPS_UART, "GPS:GGAST 0\n"); + break; + + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + + break; + } + } + + ~usrp2_gps_ctrl_impl(void){ + + } + + ptime get_time(void) { + std::string reply; + ptime now; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + _iface->write_uart(GPS_UART, "PTIME:TIME\n"); + reply = _iface->read_uart(GPS_UART, 20); + now = ptime(get_date(), duration_from_string(reply)); + break; + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_time(): Unsupported GPS or no GPS detected\n"); + break; + } + return now; + } + + date get_date(void) { + std::string reply; + date today; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + _iface->write_uart(GPS_UART, "PTIME:DATE\n"); + reply = _iface->read_uart(GPS_UART, 20); + today = from_string(reply); + break; + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_date(): Unsupported GPS or no GPS detected\n"); + break; + } + return today; + } + + bool gps_detected(void) { + return (gps_type != GPS_TYPE_NONE); + } + +private: + usrp2_iface::sptr _iface; + + enum { + GPS_TYPE_JACKSON_LABS, + GPS_TYPE_GENERIC_NMEA, + GPS_TYPE_NONE + } gps_type; + + static const int GPS_UART = 2; //TODO: this should be plucked from fw_common.h or memory_map.h or somewhere in common with the firmware + +}; + +/*********************************************************************** + * Public make function for the GPS control + **********************************************************************/ +usrp2_gps_ctrl::sptr usrp2_gps_ctrl::make(usrp2_iface::sptr iface){ + return sptr(new usrp2_gps_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp2/gps_ctrl.hpp b/host/lib/usrp/usrp2/gps_ctrl.hpp new file mode 100644 index 000000000..5936a6fb6 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.hpp @@ -0,0 +1,53 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_GPS_CTRL_HPP +#define INCLUDED_GPS_CTRL_HPP + +#include "usrp2_iface.hpp" +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + +using namespace boost::posix_time; + +class usrp2_gps_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr<usrp2_gps_ctrl> sptr; + + /*! + * Make a GPS config for Jackson Labs or generic NMEA GPS devices + */ + static sptr make(usrp2_iface::sptr iface); + + /*! + * Get the current GPS time and date + * \return current GPS time and date as boost::posix_time::ptime object + */ + virtual ptime get_time(void) = 0; + + /*! + * Tell you if there's a supported GPS connected or not + * \return true if a supported GPS is connected + */ + virtual bool gps_detected(void) = 0; + + //TODO: other fun things you can do with a GPS. + +}; + +#endif /* INCLUDED_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 96c98f6c5..ed6398405 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -51,16 +51,11 @@ usrp2_mboard_impl::usrp2_mboard_impl( //set the device revision (USRP2 or USRP2+) based on the above _iface->set_hw_rev((_rev_hi << 8) | _rev_lo); - //TODO DEBUG! this is just here to test writing to and reading from the UART. - std::string mystr = "PTIME:TIME?\n"; - _iface->write_uart(2, mystr); - mystr = _iface->read_uart(2, 20); - std::cout << "what time is it? " << mystr.c_str(); - //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); _codec_ctrl = usrp2_codec_ctrl::make(_iface); _serdes_ctrl = usrp2_serdes_ctrl::make(_iface); + _gps_ctrl = usrp2_gps_ctrl::make(_iface); //TODO move to dsp impl... //load the allowed decim/interp rates diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 21a56cb67..b37c61488 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -21,6 +21,7 @@ #include "usrp2_iface.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include "gps_ctrl.hpp" #include "serdes_ctrl.hpp" #include <uhd/device.hpp> #include <uhd/utils/pimpl.hpp> @@ -151,6 +152,7 @@ private: usrp2_clock_ctrl::sptr _clock_ctrl; usrp2_codec_ctrl::sptr _codec_ctrl; usrp2_serdes_ctrl::sptr _serdes_ctrl; + usrp2_gps_ctrl::sptr _gps_ctrl; //rx and tx dboard methods and objects uhd::usrp::dboard_manager::sptr _dboard_manager; |