diff options
Diffstat (limited to 'host/lib/usrp_clock/octoclock/octoclock_uart.cpp')
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_uart.cpp | 268 |
1 files changed, 139 insertions, 129 deletions
diff --git a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp index 7fc455dda..15c503888 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_uart.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_uart.cpp @@ -5,163 +5,173 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <iostream> -#include <string> -#include <chrono> -#include <thread> -#include <string.h> +#include "octoclock_uart.hpp" +#include "common.h" +#include <uhd/exception.hpp> +#include <uhd/utils/byteswap.hpp> #include <stdint.h> - +#include <string.h> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <boost/format.hpp> #include <boost/thread/thread.hpp> - -#include <uhd/exception.hpp> -#include <uhd/utils/byteswap.hpp> - -#include "common.h" -#include "octoclock_uart.hpp" +#include <chrono> +#include <string> +#include <thread> namespace asio = boost::asio; 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 MAX_CACHE_AGE 256 //seconds - -namespace uhd{ - 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 = uint32_t(std::rand()); - size_t len = 0; - - //Get pool size from device - octoclock_packet_t pkt_out; - pkt_out.sequence = uhd::htonx<uint32_t>(_sequence); - pkt_out.len = 0; - - 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, _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); - } - else throw uhd::runtime_error("Failed to communicate with GPSDO."); - } +#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 MAX_CACHE_AGE 256 // seconds + +namespace uhd { +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 = uint32_t(std::rand()); + size_t len = 0; + + // Get pool size from device + octoclock_packet_t pkt_out; + pkt_out.sequence = uhd::htonx<uint32_t>(_sequence); + pkt_out.len = 0; + + 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, _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); + } else + throw uhd::runtime_error("Failed to communicate with GPSDO."); +} - void octoclock_uart_iface::write_uart(const std::string &buf){ - size_t len = 0; +void octoclock_uart_iface::write_uart(const std::string& buf) +{ + size_t len = 0; - octoclock_packet_t pkt_out; - pkt_out.sequence = uhd::htonx<uint32_t>(++_sequence); - pkt_out.len = buf.size(); - memcpy(pkt_out.data, buf.c_str(), buf.size()); + octoclock_packet_t pkt_out; + pkt_out.sequence = uhd::htonx<uint32_t>(++_sequence); + pkt_out.len = buf.size(); + memcpy(pkt_out.data, buf.c_str(), buf.size()); - uint8_t octoclock_data[udp_simple::mtu]; - const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); + 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, _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."); - } + 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."); } +} - std::string octoclock_uart_iface::read_uart(double timeout){ - std::string result; - const auto exit_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(int64_t(timeout*1e3)); +std::string octoclock_uart_iface::read_uart(double timeout) +{ + std::string result; + const auto exit_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(int64_t(timeout * 1e3)); - while(true) - { - _update_cache(); + while (true) { + _update_cache(); - for(char ch = _getchar(); ch != 0; ch = _getchar()){ - _rxbuff += ch; + for (char ch = _getchar(); ch != 0; ch = _getchar()) { + _rxbuff += ch; - //If newline found, return string - if(ch == '\n'){ - result.swap(_rxbuff); - return result; - } + // If newline found, return string + if (ch == '\n') { + result.swap(_rxbuff); + return result; } - if (std::chrono::steady_clock::now() > exit_time) { - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - - return result; + if (std::chrono::steady_clock::now() > exit_time) { + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - void octoclock_uart_iface::_update_cache(){ - octoclock_packet_t pkt_out; - pkt_out.len = 0; - size_t len = 0; - - uint8_t octoclock_data[udp_simple::mtu]; - const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); - - 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<uint32_t>(++_sequence); - 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; - } + return result; +} + +void octoclock_uart_iface::_update_cache() +{ + octoclock_packet_t pkt_out; + pkt_out.len = 0; + size_t len = 0; + + uint8_t octoclock_data[udp_simple::mtu]; + const octoclock_packet_t* pkt_in = + reinterpret_cast<octoclock_packet_t*>(octoclock_data); + + 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)); - uint8_t delta_wraps = (_device_state.num_wraps - _state.num_wraps); - if(cache_expired or delta_wraps > 1 or - ((delta_wraps == 1) and (_device_state.pos > _state.pos))){ - - _state.pos = _device_state.pos; - _state.num_wraps = (_device_state.num_wraps-1); - _rxbuff.clear(); - - 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++; - } + pkt_out.sequence = uhd::htonx<uint32_t>(++_sequence); + 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; + } + + uint8_t delta_wraps = (_device_state.num_wraps - _state.num_wraps); + if (cache_expired or delta_wraps > 1 + or ((delta_wraps == 1) and (_device_state.pos > _state.pos))) { + _state.pos = _device_state.pos; + _state.num_wraps = (_device_state.num_wraps - 1); + _rxbuff.clear(); + + 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++; } } } +} - char octoclock_uart_iface::_getchar(){ - if(STATES_EQUAL){ - return 0; - } +char octoclock_uart_iface::_getchar() +{ + if (STATES_EQUAL) { + return 0; + } - char ch = _cache[_state.pos]; - _state.pos = ((_state.pos+1) % _poolsize); - //We may have wrapped around locally - if(_state.pos == 0) _state.num_wraps++; + char ch = _cache[_state.pos]; + _state.pos = ((_state.pos + 1) % _poolsize); + // We may have wrapped around locally + if (_state.pos == 0) + _state.num_wraps++; - return ch; - } + return ch; +} - 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)); - } +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)); } +} // namespace uhd |