diff options
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/usrp_clock/octoclock/common.h | 4 | ||||
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp | 9 | ||||
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp | 10 | ||||
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_impl.cpp | 20 | ||||
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_impl.hpp | 3 | ||||
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_uart.cpp | 51 | ||||
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_uart.hpp | 6 |
7 files changed, 60 insertions, 43 deletions
diff --git a/host/lib/usrp_clock/octoclock/common.h b/host/lib/usrp_clock/octoclock/common.h index 191b93d36..43c098e81 100644 --- a/host/lib/usrp_clock/octoclock/common.h +++ b/host/lib/usrp_clock/octoclock/common.h @@ -25,8 +25,8 @@ */ #ifdef __cplusplus -#define UHD_OCTOCLOCK_SEND_AND_RECV(xport, pkt_code, pkt_out, len, data) do {\ - pkt_out.proto_ver = OCTOCLOCK_FW_COMPAT_NUM; \ +#define UHD_OCTOCLOCK_SEND_AND_RECV(xport, fw_version, pkt_code, pkt_out, len, data) do {\ + pkt_out.proto_ver = fw_version; \ pkt_out.code = pkt_code; \ xport->send(boost::asio::buffer(&pkt_out, sizeof(octoclock_packet_t))); \ len = xport->recv(boost::asio::buffer(data), 2);\ diff --git a/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp b/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp index 8ac38011d..b39bc4b52 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp @@ -50,7 +50,7 @@ void octoclock_eeprom_t::_load(){ pkt_out.sequence = boost::uint32_t(std::rand()); size_t len = 0; - UHD_OCTOCLOCK_SEND_AND_RECV(xport, SEND_EEPROM_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(xport, _proto_ver, SEND_EEPROM_CMD, pkt_out, len, octoclock_data); if(UHD_OCTOCLOCK_PACKET_MATCHES(SEND_EEPROM_ACK, pkt_out, pkt_in, len)){ //MAC address byte_vector_t mac_bytes(eeprom_in->mac_addr, eeprom_in->mac_addr+6); @@ -144,7 +144,7 @@ void octoclock_eeprom_t::_store() const { eeprom_out->revision = (*this)["revision"][0]-'0'; } - UHD_OCTOCLOCK_SEND_AND_RECV(xport, BURN_EEPROM_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(xport, _proto_ver, BURN_EEPROM_CMD, pkt_out, len, octoclock_data); if(not UHD_OCTOCLOCK_PACKET_MATCHES(BURN_EEPROM_SUCCESS_ACK, pkt_out, pkt_in, len)) throw uhd::runtime_error("Error writing to OctoClock EEPROM."); } @@ -156,8 +156,9 @@ octoclock_eeprom_t::octoclock_eeprom_t(void){ /* NOP */ } -octoclock_eeprom_t::octoclock_eeprom_t(udp_simple::sptr transport){ - xport = transport; +octoclock_eeprom_t::octoclock_eeprom_t(udp_simple::sptr transport, uint32_t proto_ver) : + xport(transport), _proto_ver(proto_ver) +{ _load(); } diff --git a/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp b/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp index e12256c15..3f89a9263 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp @@ -178,7 +178,7 @@ static void octoclock_setup_session(octoclock_session_t &session, octoclock_packet_t pkt_out; const octoclock_packet_t* pkt_in = reinterpret_cast<const octoclock_packet_t*>(session.data_in); size_t len = 0; - UHD_OCTOCLOCK_SEND_AND_RECV(session.ctrl_xport, OCTOCLOCK_QUERY_CMD, pkt_out, len, session.data_in); + UHD_OCTOCLOCK_SEND_AND_RECV(session.ctrl_xport, OCTOCLOCK_FW_COMPAT_NUM, OCTOCLOCK_QUERY_CMD, pkt_out, len, session.data_in); if(UHD_OCTOCLOCK_PACKET_MATCHES(OCTOCLOCK_QUERY_ACK, pkt_out, pkt_in, len)){ session.starting_firmware_version = uhd::htonx<boost::uint32_t>(pkt_in->proto_ver); } else { @@ -244,7 +244,7 @@ static void octoclock_burn(octoclock_session_t &session){ std::cout << " -- Preparing OctoClock for firmware load..." << std::flush; pkt_out.len = session.image.size(); pkt_out.crc = session.crc; - UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, PREPARE_FW_BURN_CMD, pkt_out, len, session.data_in); + UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, OCTOCLOCK_FW_COMPAT_NUM, PREPARE_FW_BURN_CMD, pkt_out, len, session.data_in); if(UHD_OCTOCLOCK_PACKET_MATCHES(FW_BURN_READY_ACK, pkt_out, pkt_in, len)){ std::cout << "successful." << std::endl; } @@ -265,7 +265,7 @@ static void octoclock_burn(octoclock_session_t &session){ memset(pkt_out.data, 0, OCTOCLOCK_BLOCK_SIZE); memcpy((char*)pkt_out.data, &session.image[pkt_out.addr], OCTOCLOCK_BLOCK_SIZE); - UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, FILE_TRANSFER_CMD, pkt_out, len, session.data_in); + UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, OCTOCLOCK_FW_COMPAT_NUM, FILE_TRANSFER_CMD, pkt_out, len, session.data_in); if(not UHD_OCTOCLOCK_PACKET_MATCHES(FILE_TRANSFER_ACK, pkt_out, pkt_in, len)){ std::cout << std::endl; throw uhd::runtime_error("Failed to load firmware."); @@ -299,7 +299,7 @@ static void octoclock_verify(octoclock_session_t &session){ memcpy((char*)image_part, &session.image[pkt_out.addr], OCTOCLOCK_BLOCK_SIZE); cmp_len = std::min<size_t>(OCTOCLOCK_BLOCK_SIZE, session.image.size() - size_t(pkt_out.addr)); - UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, READ_FW_CMD, pkt_out, len, session.data_in); + UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, OCTOCLOCK_FW_COMPAT_NUM, READ_FW_CMD, pkt_out, len, session.data_in); if(UHD_OCTOCLOCK_PACKET_MATCHES(READ_FW_ACK, pkt_out, pkt_in, len)){ if(memcmp(pkt_in->data, image_part, cmp_len)){ std::cout << std::endl; @@ -325,7 +325,7 @@ static void octoclock_finalize(octoclock_session_t &session){ size_t len = 0; std::cout << " -- Finalizing firmware load..." << std::flush; - UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, FINALIZE_BURNING_CMD, pkt_out, len, session.data_in); + UHD_OCTOCLOCK_SEND_AND_RECV(session.fw_xport, OCTOCLOCK_FW_COMPAT_NUM, FINALIZE_BURNING_CMD, pkt_out, len, session.data_in); if(UHD_OCTOCLOCK_PACKET_MATCHES(FINALIZE_BURNING_ACK, pkt_out, pkt_in, len)){ std::cout << "successful." << std::endl; } diff --git a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp index 7ca83ddb1..297983c15 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp @@ -138,7 +138,7 @@ device_addrs_t octoclock_find(const device_addr_t &hint){ new_addr["addr"], BOOST_STRINGIZE(OCTOCLOCK_UDP_CTRL_PORT) ); - UHD_OCTOCLOCK_SEND_AND_RECV(ctrl_xport, OCTOCLOCK_QUERY_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(ctrl_xport, OCTOCLOCK_FW_COMPAT_NUM, OCTOCLOCK_QUERY_CMD, pkt_out, len, octoclock_data); if(UHD_OCTOCLOCK_PACKET_MATCHES(OCTOCLOCK_QUERY_ACK, pkt_out, pkt_in, len)){ //If the OctoClock is in its bootloader, don't ask for details if(pkt_in->proto_ver == OCTOCLOCK_BOOTLOADER_PROTO_VER){ @@ -149,7 +149,7 @@ device_addrs_t octoclock_find(const device_addr_t &hint){ new_addr["type"] = "octoclock"; if(pkt_in->proto_ver >= OCTOCLOCK_FW_MIN_COMPAT_NUM and pkt_in->proto_ver <= OCTOCLOCK_FW_COMPAT_NUM) { - octoclock_eeprom_t oc_eeprom(ctrl_xport); + octoclock_eeprom_t oc_eeprom(ctrl_xport, pkt_in->proto_ver); new_addr["name"] = oc_eeprom["name"]; new_addr["serial"] = oc_eeprom["serial"]; } else { @@ -226,21 +226,21 @@ octoclock_impl::octoclock_impl(const device_addr_t &_device_addr){ //////////////////////////////////////////////////////////////////// // Check the firmware compatibility number //////////////////////////////////////////////////////////////////// - boost::uint32_t fw_version = _get_fw_version(oc); - if(fw_version < OCTOCLOCK_FW_MIN_COMPAT_NUM or fw_version > OCTOCLOCK_FW_COMPAT_NUM){ + _proto_ver = _get_fw_version(oc); + if(_proto_ver < OCTOCLOCK_FW_MIN_COMPAT_NUM or _proto_ver > OCTOCLOCK_FW_COMPAT_NUM){ throw uhd::runtime_error(str(boost::format( "\n\nPlease update your OctoClock's firmware.\n" "Expected firmware compatibility number %d, but got %d:\n" "The firmware build is not compatible with the host code build.\n\n" "%s\n" - ) % int(OCTOCLOCK_FW_COMPAT_NUM) % int(fw_version) % _get_images_help_message(addr))); + ) % int(OCTOCLOCK_FW_COMPAT_NUM) % int(_proto_ver) % _get_images_help_message(addr))); } - _tree->create<std::string>(oc_path / "fw_version").set(boost::lexical_cast<std::string>(int(fw_version))); + _tree->create<std::string>(oc_path / "fw_version").set(boost::lexical_cast<std::string>(int(_proto_ver))); //////////////////////////////////////////////////////////////////// // Set up EEPROM //////////////////////////////////////////////////////////////////// - _oc_dict[oc].eeprom = octoclock_eeprom_t(_oc_dict[oc].ctrl_xport); + _oc_dict[oc].eeprom = octoclock_eeprom_t(_oc_dict[oc].ctrl_xport, _proto_ver); _tree->create<octoclock_eeprom_t>(oc_path / "eeprom") .set(_oc_dict[oc].eeprom) .add_coerced_subscriber(boost::bind(&octoclock_impl::_set_eeprom, this, oc, _1)); @@ -272,7 +272,7 @@ octoclock_impl::octoclock_impl(const device_addr_t &_device_addr){ _get_state(oc); if(_oc_dict[oc].state.gps_detected){ try{ - _oc_dict[oc].gps = gps_ctrl::make(octoclock_make_uart_iface(_oc_dict[oc].gpsdo_xport)); + _oc_dict[oc].gps = gps_ctrl::make(octoclock_make_uart_iface(_oc_dict[oc].gpsdo_xport, _proto_ver)); if(_oc_dict[oc].gps and _oc_dict[oc].gps->gps_detected()){ BOOST_FOREACH(const std::string &name, _oc_dict[oc].gps->get_sensors()){ @@ -339,7 +339,7 @@ boost::uint32_t octoclock_impl::_get_fw_version(const std::string &oc){ boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); - UHD_OCTOCLOCK_SEND_AND_RECV(_oc_dict[oc].ctrl_xport, OCTOCLOCK_QUERY_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(_oc_dict[oc].ctrl_xport, OCTOCLOCK_FW_COMPAT_NUM, OCTOCLOCK_QUERY_CMD, pkt_out, len, octoclock_data); if(UHD_OCTOCLOCK_PACKET_MATCHES(OCTOCLOCK_QUERY_ACK, pkt_out, pkt_in, len)){ return pkt_in->proto_ver; } @@ -355,7 +355,7 @@ void octoclock_impl::_get_state(const std::string &oc){ boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); - UHD_OCTOCLOCK_SEND_AND_RECV(_oc_dict[oc].ctrl_xport, SEND_STATE_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(_oc_dict[oc].ctrl_xport, _proto_ver, SEND_STATE_CMD, pkt_out, len, octoclock_data); if(UHD_OCTOCLOCK_PACKET_MATCHES(SEND_STATE_ACK, pkt_out, pkt_in, len)){ const octoclock_state_t *state = reinterpret_cast<const octoclock_state_t*>(pkt_in->data); _oc_dict[oc].state = *state; diff --git a/host/lib/usrp_clock/octoclock/octoclock_impl.hpp b/host/lib/usrp_clock/octoclock/octoclock_impl.hpp index 453e75ec5..2c74b9b03 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_impl.hpp +++ b/host/lib/usrp_clock/octoclock/octoclock_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright 2014 Ettus Research LLC +// Copyright 2014,2016 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 @@ -57,6 +57,7 @@ private: }; uhd::dict<std::string, oc_container_type> _oc_dict; boost::uint32_t _sequence; + boost::uint32_t _proto_ver; void _set_eeprom(const std::string &oc, const uhd::usrp_clock::octoclock_eeprom_t &oc_eeprom); diff --git a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp index e0a9f08cf..221a7e471 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp @@ -37,16 +37,16 @@ using namespace uhd::transport; #define NUM_WRAPS_EQUAL (_state.num_wraps == _device_state.num_wraps) #define POS_EQUAL (_state.pos == _device_state.pos) #define STATES_EQUAL (NUM_WRAPS_EQUAL && POS_EQUAL) -#define LOCAL_STATE_AHEAD (_state.num_wraps > _device_state.num_wraps || \ - (NUM_WRAPS_EQUAL && _state.pos > _device_state.pos)) +#define MAX_CACHE_AGE 256 //seconds namespace uhd{ - octoclock_uart_iface::octoclock_uart_iface(udp_simple::sptr udp): uart_iface(){ + octoclock_uart_iface::octoclock_uart_iface(udp_simple::sptr udp, uint32_t proto_ver): uart_iface(){ _udp = udp; _state.num_wraps = 0; _state.pos = 0; _device_state.num_wraps = 0; _device_state.pos = 0; + _proto_ver = proto_ver; // To avoid replicating sequence numbers between sessions _sequence = boost::uint32_t(std::rand()); size_t len = 0; @@ -59,7 +59,7 @@ namespace uhd{ boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); - UHD_OCTOCLOCK_SEND_AND_RECV(_udp, SEND_POOLSIZE_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(_udp, _proto_ver, SEND_POOLSIZE_CMD, pkt_out, len, octoclock_data); if(UHD_OCTOCLOCK_PACKET_MATCHES(SEND_POOLSIZE_ACK, pkt_out, pkt_in, len)){ _poolsize = pkt_in->poolsize; _cache.resize(_poolsize); @@ -79,7 +79,7 @@ namespace uhd{ boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); - UHD_OCTOCLOCK_SEND_AND_RECV(_udp, HOST_SEND_TO_GPSDO_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(_udp, _proto_ver, HOST_SEND_TO_GPSDO_CMD, pkt_out, len, octoclock_data); if(not UHD_OCTOCLOCK_PACKET_MATCHES(HOST_SEND_TO_GPSDO_ACK, pkt_out, pkt_in, len)){ throw uhd::runtime_error("Failed to send commands to GPSDO."); } @@ -87,10 +87,15 @@ namespace uhd{ std::string octoclock_uart_iface::read_uart(double timeout){ std::string result; - + bool first_time = true; boost::system_time exit_time = boost::get_system_time() + boost::posix_time::milliseconds(long(timeout*1e3)); while(boost::get_system_time() < exit_time){ + if (first_time) + first_time = false; + else + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + _update_cache(); for(char ch = _getchar(); ch != 0; ch = _getchar()){ @@ -104,7 +109,6 @@ namespace uhd{ return result; } } - boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } return result; @@ -118,35 +122,44 @@ namespace uhd{ boost::uint8_t octoclock_data[udp_simple::mtu]; const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); - if(STATES_EQUAL or LOCAL_STATE_AHEAD){ + if(STATES_EQUAL){ + boost::system_time time = boost::get_system_time(); + boost::posix_time::time_duration age = time - _last_cache_update; + bool cache_expired = (age > boost::posix_time::seconds(MAX_CACHE_AGE)); + pkt_out.sequence = uhd::htonx<boost::uint32_t>(++_sequence); - UHD_OCTOCLOCK_SEND_AND_RECV(_udp, SEND_GPSDO_CACHE_CMD, pkt_out, len, octoclock_data); + UHD_OCTOCLOCK_SEND_AND_RECV(_udp, _proto_ver, SEND_GPSDO_CACHE_CMD, pkt_out, len, octoclock_data); if(UHD_OCTOCLOCK_PACKET_MATCHES(SEND_GPSDO_CACHE_ACK, pkt_out, pkt_in, len)){ memcpy(&_cache[0], pkt_in->data, _poolsize); _device_state = pkt_in->state; + _last_cache_update = time; } boost::uint8_t delta_wraps = (_device_state.num_wraps - _state.num_wraps); - if(delta_wraps > 1 or - ((delta_wraps == 1) and (_device_state.pos >= _state.pos))){ + if(cache_expired or delta_wraps > 1 or + ((delta_wraps == 1) and (_device_state.pos > _state.pos))){ - _state.pos = (_device_state.pos+1) % _poolsize; + _state.pos = _device_state.pos; _state.num_wraps = (_device_state.num_wraps-1); + _rxbuff.clear(); - while((_cache[_state.pos] != '\n') and (_state.pos != _device_state.pos)){ + while((_cache[_state.pos] != '\n')){ + _state.pos = (_state.pos+1) % _poolsize; + //We may have wrapped around locally + if(_state.pos == 0) _state.num_wraps++; + if(STATES_EQUAL) break; + } + if (_cache[_state.pos] == '\n'){ _state.pos = (_state.pos+1) % _poolsize; //We may have wrapped around locally if(_state.pos == 0) _state.num_wraps++; } - if (_cache[_state.pos] == '\n') _state.pos = (_state.pos+1) % _poolsize; - //We may have wrapped around locally - if(_state.pos == 0) _state.num_wraps++; } } } char octoclock_uart_iface::_getchar(){ - if(STATES_EQUAL or LOCAL_STATE_AHEAD){ + if(STATES_EQUAL){ return 0; } @@ -158,7 +171,7 @@ namespace uhd{ return ch; } - uart_iface::sptr octoclock_make_uart_iface(udp_simple::sptr udp){ - return uart_iface::sptr(new octoclock_uart_iface(udp)); + uart_iface::sptr octoclock_make_uart_iface(udp_simple::sptr udp, uint32_t proto_ver){ + return uart_iface::sptr(new octoclock_uart_iface(udp, proto_ver)); } } diff --git a/host/lib/usrp_clock/octoclock/octoclock_uart.hpp b/host/lib/usrp_clock/octoclock/octoclock_uart.hpp index d7a77288f..d3a9738c4 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_uart.hpp +++ b/host/lib/usrp_clock/octoclock/octoclock_uart.hpp @@ -31,7 +31,7 @@ namespace uhd{ class octoclock_uart_iface : public uhd::uart_iface{ public: - octoclock_uart_iface(uhd::transport::udp_simple::sptr udp); + octoclock_uart_iface(uhd::transport::udp_simple::sptr udp, uint32_t proto_ver); ~octoclock_uart_iface(void) {}; void write_uart(const std::string &buf); @@ -46,12 +46,14 @@ private: std::vector<boost::uint8_t> _cache; std::string _rxbuff; boost::uint32_t _sequence; + boost::uint32_t _proto_ver; + boost::system_time _last_cache_update; void _update_cache(); char _getchar(); }; -uart_iface::sptr octoclock_make_uart_iface(uhd::transport::udp_simple::sptr udp); +uart_iface::sptr octoclock_make_uart_iface(uhd::transport::udp_simple::sptr udp, uint32_t proto_ver); } |