1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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));
}
|