aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2016-09-02 11:27:37 -0700
committerMartin Braun <martin.braun@ettus.com>2016-09-02 11:27:37 -0700
commit83912104a9c1ab3631f755a4d98ee86e195db690 (patch)
tree4c7ba7da761b1b9b5508bffdb77b9e0696ff46ae /host/lib/usrp
parent670eeda6e4c9ff2ab81f4e387bce49ea4dc79dcc (diff)
parent065065e90ce970f8eed0941ded6ae4377e649c2b (diff)
downloaduhd-83912104a9c1ab3631f755a4d98ee86e195db690.tar.gz
uhd-83912104a9c1ab3631f755a4d98ee86e195db690.tar.bz2
uhd-83912104a9c1ab3631f755a4d98ee86e195db690.zip
Merge branch 'UHD-3.9.LTS' into maint
This provides the GPS fixes. Conflicts: host/CMakeLists.txt tools/debs/upload_debs.sh
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp8
-rw-r--r--host/lib/usrp/b200/b200_uart.cpp36
-rw-r--r--host/lib/usrp/b200/b200_uart.hpp1
-rw-r--r--host/lib/usrp/e100/e100_ctrl.cpp15
-rw-r--r--host/lib/usrp/gps_ctrl.cpp241
-rw-r--r--host/lib/usrp/x300/x300_fw_uart.cpp32
6 files changed, 174 insertions, 159 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index aed1204d3..33f0850eb 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -461,6 +461,10 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
////////////////////////////////////////////////////////////////////
_async_task_data.reset(new AsyncTaskData());
_async_task_data->async_md.reset(new async_md_type(1000/*messages deep*/));
+ if (_gpsdo_capable)
+ {
+ _async_task_data->gpsdo_uart = b200_uart::make(_ctrl_transport, B200_TX_GPS_UART_SID);
+ }
_async_task = uhd::msg_task::make(boost::bind(&b200_impl::handle_async_task, this, _ctrl_transport, _async_task_data));
////////////////////////////////////////////////////////////////////
@@ -481,10 +485,6 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
////////////////////////////////////////////////////////////////////
if (_gpsdo_capable)
{
- _async_task_data->gpsdo_uart = b200_uart::make(_ctrl_transport, B200_TX_GPS_UART_SID);
- _async_task_data->gpsdo_uart->set_baud_divider(B200_BUS_CLOCK_RATE/115200);
- _async_task_data->gpsdo_uart->write_uart("\n"); //cause the baud and response to be setup
- boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for a little propagation
if ((_local_ctrl->peek32(RB32_CORE_STATUS) & 0xff) != B200_GPSDO_ST_NONE)
{
diff --git a/host/lib/usrp/b200/b200_uart.cpp b/host/lib/usrp/b200/b200_uart.cpp
index 4682a79b9..065aa49ce 100644
--- a/host/lib/usrp/b200/b200_uart.cpp
+++ b/host/lib/usrp/b200/b200_uart.cpp
@@ -16,12 +16,14 @@
//
#include "b200_uart.hpp"
+#include "b200_impl.hpp"
#include <uhd/transport/bounded_buffer.hpp>
#include <uhd/transport/vrt_if_packet.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/types/time_spec.hpp>
#include <uhd/exception.hpp>
+#include <boost/foreach.hpp>
using namespace uhd;
using namespace uhd::transport;
@@ -32,10 +34,10 @@ struct b200_uart_impl : b200_uart
_xport(xport),
_sid(sid),
_count(0),
- _char_queue(4096)
+ _baud_div(std::floor(B200_BUS_CLOCK_RATE/115200 + 0.5)),
+ _line_queue(4096)
{
- //this default baud divider is over 9000
- this->set_baud_divider(9001);
+ /*NOP*/
}
void send_char(const char ch)
@@ -67,23 +69,16 @@ struct b200_uart_impl : b200_uart
void write_uart(const std::string &buff)
{
- for (size_t i = 0; i < buff.size(); i++)
+ BOOST_FOREACH(const char ch, buff)
{
- if (buff[i] == '\n') this->send_char('\r');
- this->send_char(buff[i]);
+ this->send_char(ch);
}
}
std::string read_uart(double timeout)
{
std::string line;
- char ch = '\0';
- while (_char_queue.pop_with_timed_wait(ch, timeout))
- {
- if (ch == '\r') continue;
- line += std::string(&ch, 1);
- if (ch == '\n') return line;
- }
+ _line_queue.pop_with_timed_wait(line, timeout);
return line;
}
@@ -95,19 +90,20 @@ struct b200_uart_impl : b200_uart
packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
vrt::if_hdr_unpack_le(packet_buff, packet_info);
const char ch = char(uhd::wtohx(packet_buff[packet_info.num_header_words32+1]));
- _char_queue.push_with_pop_on_full(ch);
- }
-
- void set_baud_divider(const double baud_div)
- {
- _baud_div = size_t(baud_div + 0.5);
+ _line += ch;
+ if (ch == '\n')
+ {
+ _line_queue.push_with_pop_on_full(_line);
+ _line.clear();
+ }
}
const zero_copy_if::sptr _xport;
const boost::uint32_t _sid;
size_t _count;
size_t _baud_div;
- bounded_buffer<char> _char_queue;
+ bounded_buffer<std::string> _line_queue;
+ std::string _line;
};
diff --git a/host/lib/usrp/b200/b200_uart.hpp b/host/lib/usrp/b200/b200_uart.hpp
index 1c8e44ddc..f58479888 100644
--- a/host/lib/usrp/b200/b200_uart.hpp
+++ b/host/lib/usrp/b200/b200_uart.hpp
@@ -29,7 +29,6 @@ public:
typedef boost::shared_ptr<b200_uart> sptr;
static sptr make(uhd::transport::zero_copy_if::sptr, const boost::uint32_t sid);
virtual void handle_uart_packet(uhd::transport::managed_recv_buffer::sptr buff) = 0;
- virtual void set_baud_divider(const double baud_div) = 0;
};
diff --git a/host/lib/usrp/e100/e100_ctrl.cpp b/host/lib/usrp/e100/e100_ctrl.cpp
index cdbbff6dd..c164a6fb0 100644
--- a/host/lib/usrp/e100/e100_ctrl.cpp
+++ b/host/lib/usrp/e100/e100_ctrl.cpp
@@ -232,10 +232,13 @@ public:
//got a character -> process it
if (ret == 1){
- const bool flush = ch == '\n' or ch == '\r';
- if (flush and line.empty()) continue; //avoid flushing on empty lines
- line += std::string(1, ch);
- if (flush) break;
+ _line += ch;
+ if (ch == '\n')
+ {
+ line = _line;
+ _line.clear();
+ break;
+ }
}
//didnt get a character, check the timeout
@@ -251,7 +254,9 @@ public:
return line;
}
-private: int _node_fd;
+private:
+ int _node_fd;
+ std::string _line;
};
uhd::uart_iface::sptr e100_ctrl::make_gps_uart_iface(const std::string &node){
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index 207ef10ab..908f84a00 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -28,6 +28,7 @@
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>
+#include <boost/thread/mutex.hpp>
#include "boost/tuple/tuple.hpp"
#include "boost/foreach.hpp"
@@ -48,24 +49,68 @@ gps_ctrl::~gps_ctrl(void){
class gps_ctrl_impl : public gps_ctrl{
private:
- std::map<std::string, boost::tuple<std::string, boost::system_time, bool> > sensors;
+ std::map<std::string, boost::tuple<std::string, boost::system_time, bool> > sentences;
+ boost::mutex cache_mutex;
+ boost::system_time _last_cache_update;
- std::string get_cached_sensor(const std::string sensor, const int freshness, const bool once, const bool touch=true) {
- boost::system_time time = boost::get_system_time();
- try {
- // this is nasty ...
- //std::cout << boost::format("Requested %s - seen? ") % sensor << sensors[sensor].get<2>() << " once? " << once << std::endl;
- if(time - sensors[sensor].get<1>() < milliseconds(freshness) && (!once or !sensors[sensor].get<2>())) {
- sensors[sensor] = boost::make_tuple(sensors[sensor].get<0>(), sensors[sensor].get<1>(), touch);
- return sensors[sensor].get<0>();
- } else {
- return update_cached_sensors(sensor);
- }
- } catch(std::exception &e) {
- UHD_MSG(warning) << "get_cached_sensor: " << e.what();
+ std::string get_sentence(const std::string which, const int max_age_ms, const int timeout, const bool wait_for_next = false)
+ {
+ std::string sentence;
+ boost::system_time now = boost::get_system_time();
+ boost::system_time exit_time = now + milliseconds(timeout);
+ boost::posix_time::time_duration age;
+
+ if (wait_for_next)
+ {
+ boost::lock_guard<boost::mutex> lock(cache_mutex);
+ update_cache();
+ //mark sentence as touched
+ if (sentences.find(which) != sentences.end())
+ sentences[which].get<2>() = true;
+ }
+ while (1)
+ {
+ try
+ {
+ boost::lock_guard<boost::mutex> lock(cache_mutex);
+
+ // update cache if older than a millisecond
+ if (now - _last_cache_update > milliseconds(1))
+ {
+ update_cache();
+ }
+
+ if (sentences.find(which) == sentences.end())
+ {
+ age = milliseconds(max_age_ms);
+ } else {
+ age = boost::get_system_time() - sentences[which].get<1>();
+ }
+ if (age < milliseconds(max_age_ms) and (not (wait_for_next and sentences[which].get<2>())))
+ {
+ sentence = sentences[which].get<0>();
+ sentences[which].get<2>() = true;
+ }
+ } catch(std::exception &e) {
+ UHD_MSG(warning) << "get_sentence: " << e.what();
+ }
+
+ if (not sentence.empty() or now > exit_time)
+ {
+ break;
+ }
+
+ sleep(boost::posix_time::milliseconds(1));
+ now = boost::get_system_time();
+ }
+
+ if (sentence.empty())
+ {
+ throw uhd::value_error("gps ctrl: No " + which + " message found");
+ }
+
+ return sentence;
}
- return std::string();
- }
static bool is_nmea_checksum_ok(std::string nmea)
{
@@ -88,33 +133,39 @@ private:
return (string_crc == calculated_crc);
}
- std::string update_cached_sensors(const std::string sensor) {
- if(not gps_detected() || (gps_type != GPS_TYPE_INTERNAL_GPSDO)) {
+ void update_cache() {
+ if(not gps_detected() or (_gps_type != GPS_TYPE_INTERNAL_GPSDO)) {
UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected";
- return std::string();
+ return;
}
- const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC")("SERVO");
- static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d");
+ const std::list<std::string> keys = boost::assign::list_of("GPGGA")("GPRMC")("SERVO");
+ static const boost::regex servo_regex("^\\d\\d-\\d\\d-\\d\\d.*$");
static const boost::regex gp_msg_regex("^\\$GP.*,\\*[0-9A-F]{2}$");
std::map<std::string,std::string> msgs;
// Get all GPSDO messages available
// Creating a map here because we only want the latest of each message type
- for (std::string msg = _recv(); msg.length(); msg = _recv())
+ for (std::string msg = _recv(0); not msg.empty(); msg = _recv(0))
{
// Strip any end of line characters
erase_all(msg, "\r");
erase_all(msg, "\n");
+ if (msg.empty())
+ {
+ // Ignore empty strings
+ continue;
+ }
+
if (msg.length() < 6)
{
- UHD_LOGV(regularly) << __FUNCTION__ << ": Short NMEA string: " << msg << std::endl;
+ UHD_LOGV(regularly) << __FUNCTION__ << ": Short GPSDO string: " << msg << std::endl;
continue;
}
// Look for SERVO message
- if (boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous))
+ if (boost::regex_search(msg, servo_regex, boost::regex_constants::match_continuous))
{
msgs["SERVO"] = msg;
}
@@ -124,62 +175,63 @@ private:
}
else
{
- UHD_LOGV(regularly) << __FUNCTION__ << ": Malformed NMEA string: " << msg << std::endl;
+ UHD_LOGV(regularly) << __FUNCTION__ << ": Malformed GPSDO string: " << msg << std::endl;
}
}
boost::system_time time = boost::get_system_time();
- // Update sensors with newly read data
- BOOST_FOREACH(std::string key, list) {
- if (msgs[key].length())
- sensors[key] = boost::make_tuple(msgs[key], time, !sensor.compare(key));
+ // Update sentences with newly read data
+ BOOST_FOREACH(std::string key, keys)
+ {
+ if (not msgs[key].empty())
+ {
+ sentences[key] = boost::make_tuple(msgs[key], time, false);
+ }
}
- // Return requested sensor if it was updated
- if (msgs[sensor].length())
- return msgs[sensor];
-
- return std::string();
+ _last_cache_update = time;
}
public:
- gps_ctrl_impl(uart_iface::sptr uart){
- _uart = uart;
-
+ gps_ctrl_impl(uart_iface::sptr uart) :
+ _uart(uart),
+ _gps_type(GPS_TYPE_NONE)
+ {
std::string reply;
bool i_heard_some_nmea = false, i_heard_something_weird = false;
- gps_type = GPS_TYPE_NONE;
//first we look for an internal GPSDO
_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 GPSDO
-
- //wait for _send(...) to return
- sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
+ _send("*IDN?\r\n"); //request identity from the GPSDO
//then we loop until we either timeout, or until we get a response that indicates we're a JL device
const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
while(boost::get_system_time() < comm_timeout) {
reply = _recv();
- if(reply.find("Command Error") != std::string::npos) {
- gps_type = GPS_TYPE_INTERNAL_GPSDO;
+ //known devices are JL "FireFly" and "LC_XO"
+ if(reply.find("FireFly") != std::string::npos or reply.find("LC_XO") != std::string::npos) {
+ _gps_type = GPS_TYPE_INTERNAL_GPSDO;
break;
+ } else if(reply.substr(0, 3) == "$GP") {
+ i_heard_some_nmea = true; //but keep looking
+ } else if(not reply.empty()) {
+ i_heard_something_weird = true; //probably wrong baud rate
}
- else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response
- else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate
}
- if((i_heard_some_nmea) && (gps_type != GPS_TYPE_INTERNAL_GPSDO)) gps_type = GPS_TYPE_GENERIC_NMEA;
+ if((i_heard_some_nmea) && (_gps_type != GPS_TYPE_INTERNAL_GPSDO)) _gps_type = GPS_TYPE_GENERIC_NMEA;
- if((gps_type == GPS_TYPE_NONE) && i_heard_something_weird) {
+ if((_gps_type == GPS_TYPE_NONE) && i_heard_something_weird) {
UHD_MSG(error) << "GPS invalid reply \"" << reply << "\", assuming none available" << std::endl;
}
- switch(gps_type) {
+ switch(_gps_type) {
case GPS_TYPE_INTERNAL_GPSDO:
- UHD_MSG(status) << "Found an internal GPSDO" << std::endl;
+ erase_all(reply, "\r");
+ erase_all(reply, "\n");
+ UHD_MSG(status) << "Found an internal GPSDO: " << reply << std::endl;
init_gpsdo();
break;
@@ -193,6 +245,9 @@ public:
break;
}
+
+ // initialize cache
+ update_cache();
}
~gps_ctrl_impl(void){
@@ -215,7 +270,7 @@ public:
or key == "gps_gprmc") {
return sensor_value_t(
boost::to_upper_copy(key),
- get_cached_sensor(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, false, false),
+ get_sentence(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, GPS_TIMEOUT_DELAY_MS),
"");
}
else if(key == "gps_time") {
@@ -225,7 +280,10 @@ public:
return sensor_value_t("GPS lock status", locked(), "locked", "unlocked");
}
else if(key == "gps_servo") {
- return sensor_value_t("GPS servo status", get_servo(), "");
+ return sensor_value_t(
+ boost::to_upper_copy(key),
+ get_sentence(boost::to_upper_copy(key.substr(4,8)), GPS_SERVO_FRESHNESS, GPS_TIMEOUT_DELAY_MS),
+ "");
}
else {
throw uhd::value_error("gps ctrl get_sensor unknown key: " + key);
@@ -238,40 +296,20 @@ private:
//none of these should issue replies so we don't bother looking for them
//we have to sleep between commands because the JL device, despite not acking, takes considerable time to process each command.
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
- _send("SYST:COMM:SER:ECHO OFF\n");
+ _send("SYST:COMM:SER:ECHO OFF\r\n");
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
- _send("SYST:COMM:SER:PRO OFF\n");
+ _send("SYST:COMM:SER:PRO OFF\r\n");
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
- _send("GPS:GPGGA 1\n");
+ _send("GPS:GPGGA 1\r\n");
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
- _send("GPS:GGAST 0\n");
+ _send("GPS:GGAST 0\r\n");
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
- _send("GPS:GPRMC 1\n");
+ _send("GPS:GPRMC 1\r\n");
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
- _send("SERV:TRAC 0\n");
+ _send("SERV:TRAC 1\r\n");
sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
}
- //retrieve a raw NMEA sentence
- std::string get_nmea(std::string msgtype) {
- std::string reply;
-
- const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
- while(boost::get_system_time() < comm_timeout) {
- if(!msgtype.compare("GPRMC")) {
- reply = get_cached_sensor(msgtype, GPS_NMEA_FRESHNESS, true);
- }
- else {
- reply = get_cached_sensor(msgtype, GPS_NMEA_LOW_FRESHNESS, false);
- }
- if(reply.size()) {
- if(reply.substr(1, 5) == msgtype) return reply;
- }
- boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
- }
- throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype));
- }
-
//helper function to retrieve a field from an NMEA sentence
std::string get_token(std::string sentence, size_t offset) {
boost::tokenizer<boost::escaped_list_separator<char> > tok(sentence);
@@ -286,12 +324,12 @@ private:
}
ptime get_time(void) {
- _flush();
int error_cnt = 0;
ptime gps_time;
while(error_cnt < 2) {
try {
- std::string reply = get_nmea("GPRMC");
+ // wait for next GPRMC string
+ std::string reply = get_sentence("GPRMC", GPS_NMEA_NORMAL_FRESHNESS, GPS_COMM_TIMEOUT_MS, true);
std::string datestr = get_token(reply, 9);
std::string timestr = get_token(reply, 1);
@@ -314,7 +352,6 @@ private:
} catch(std::exception &e) {
UHD_MSG(warning) << "get_time: " << e.what();
- _flush();
error_cnt++;
}
}
@@ -328,46 +365,24 @@ private:
}
bool gps_detected(void) {
- return (gps_type != GPS_TYPE_NONE);
+ return (_gps_type != GPS_TYPE_NONE);
}
bool locked(void) {
int error_cnt = 0;
while(error_cnt < 3) {
try {
- std::string reply = get_cached_sensor("GPGGA", GPS_LOCK_FRESHNESS, false, false);
- if(reply.size() <= 1) return false;
-
- return (get_token(reply, 6) != "0");
+ std::string reply = get_sentence("GPGGA", GPS_LOCK_FRESHNESS, GPS_COMM_TIMEOUT_MS);
+ if(reply.empty())
+ error_cnt++;
+ else
+ return (get_token(reply, 6) != "0");
} catch(std::exception &e) {
UHD_MSG(warning) << "locked: " << e.what();
error_cnt++;
}
}
- throw uhd::value_error("Timeout after no valid message found");
- return false;
- }
-
- std::string get_servo(void) {
-
- //enable servo reporting
- _send("SERV:TRAC 1\n");
- sleep(milliseconds(GPSDO_COMMAND_DELAY_MS));
-
- std::string reply;
-
- const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
- while(boost::get_system_time() < comm_timeout) {
- reply = get_cached_sensor("SERVO", GPS_NMEA_LOW_FRESHNESS, false);
- if(reply.size())
- {
- //disable it before leaving function
- _send("SERV:TRAC 0\n");
- return reply;
- }
- boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
- }
- throw uhd::value_error("get_stat(): no servo message found");
+ throw uhd::value_error("locked(): unable to determine GPS lock status");
}
uart_iface::sptr _uart;
@@ -390,13 +405,11 @@ private:
GPS_TYPE_INTERNAL_GPSDO,
GPS_TYPE_GENERIC_NMEA,
GPS_TYPE_NONE
- } gps_type;
+ } _gps_type;
static const int GPS_COMM_TIMEOUT_MS = 1300;
- static const int GPS_NMEA_FRESHNESS = 10;
- static const int GPS_NMEA_LOW_FRESHNESS = 2500;
static const int GPS_NMEA_NORMAL_FRESHNESS = 1000;
- static const int GPS_SERVO_FRESHNESS = 2500;
+ static const int GPS_SERVO_FRESHNESS = 1000;
static const int GPS_LOCK_FRESHNESS = 2500;
static const int GPS_TIMEOUT_DELAY_MS = 200;
static const int GPSDO_COMMAND_DELAY_MS = 200;
diff --git a/host/lib/usrp/x300/x300_fw_uart.cpp b/host/lib/usrp/x300/x300_fw_uart.cpp
index b0fae124d..7f60e26fc 100644
--- a/host/lib/usrp/x300/x300_fw_uart.cpp
+++ b/host/lib/usrp/x300/x300_fw_uart.cpp
@@ -30,28 +30,36 @@ using namespace uhd;
struct x300_uart_iface : uart_iface
{
x300_uart_iface(wb_iface::sptr iface):
- rxoffset(0), txoffset(0), txword32(0), rxpool(0), txpool(0), poolsize(0)
+ _iface(iface),
+ rxoffset(0),
+ txword32(0),
+ _last_device_rxoffset(0)
{
- _iface = iface;
- rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX));
txoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX));
rxpool = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_ADDR));
txpool = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_ADDR));
poolsize = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_WORDS32));
_rxcache.resize(poolsize);
- _last_device_rxoffset = rxoffset;
//this->write_uart("HELLO UART\n");
//this->read_uart(0.1);
}
void putchar(const char ch)
{
- txoffset = (txoffset + 1) % (poolsize*4);
const int shift = ((txoffset%4) * 8);
if (shift == 0) txword32 = 0;
txword32 |= boost::uint32_t(ch) << shift;
- _iface->poke32(SR_ADDR(txpool, txoffset/4), txword32);
- _iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX), txoffset);
+ // Write out full 32 bit words or whatever we have if end of string
+ if (txoffset % 4 == 3 or ch == '\n')
+ {
+ _iface->poke32(SR_ADDR(txpool, txoffset/4), txword32);
+ }
+ txoffset = (txoffset + 1) % (poolsize*4);
+ if (ch == '\n')
+ {
+ // Tell the X300 to write the string
+ _iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX), txoffset);
+ }
}
void write_uart(const std::string &buff)
@@ -59,7 +67,6 @@ struct x300_uart_iface : uart_iface
boost::mutex::scoped_lock(_write_mutex);
BOOST_FOREACH(const char ch, buff)
{
- if (ch == '\n') this->putchar('\r');
this->putchar(ch);
}
}
@@ -128,18 +135,13 @@ struct x300_uart_iface : uart_iface
// Get available characters
for (int ch = this->getchar(); ch != -1; ch = this->getchar())
{
- // skip carriage returns
- if (ch == '\r')
- continue;
-
// store character to buffer
- _rxbuff += std::string(1, (char)ch);
+ _rxbuff.append(1, ch);
// newline found - return string
if (ch == '\n')
{
- buff = _rxbuff;
- _rxbuff.clear();
+ buff.swap(_rxbuff);
return buff;
}
}