diff options
author | Nicholas Corgan <nick.corgan@ettus.com> | 2014-08-15 12:57:10 -0700 |
---|---|---|
committer | Nicholas Corgan <nick.corgan@ettus.com> | 2014-08-20 09:42:26 -0700 |
commit | 2de96cd57c3f19bfa778ccad280ad19170af0967 (patch) | |
tree | 88e5235bbbc1df0dd5d6ce1883203a09f3e07ea3 /host | |
parent | 9fb6c2919ad9e7e736c837186861b362ba80cdfa (diff) | |
download | uhd-2de96cd57c3f19bfa778ccad280ad19170af0967.tar.gz uhd-2de96cd57c3f19bfa778ccad280ad19170af0967.tar.bz2 uhd-2de96cd57c3f19bfa778ccad280ad19170af0967.zip |
OctoClock: bugfixes/improvements
* Fixed Ethernet initialization problem
* Improved external reference detection
* Added gratuitous ARP, sent upon power-up
* Tweaked host-side timing for initialization and firmware burning
* Fixed logic for dealing with firmware incompatibility
* Misc efficiency/reliability improvements to firmware's network code
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/usrp_clock/octoclock/octoclock_impl.cpp | 9 | ||||
-rw-r--r-- | host/utils/octoclock_firmware_burner.cpp | 57 |
2 files changed, 43 insertions, 23 deletions
diff --git a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp index add5d7931..8c207dd9f 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_impl.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_impl.cpp @@ -75,7 +75,7 @@ device_addrs_t octoclock_find(const device_addr_t &hint){ device_addr_t _hint = hints[0]; device_addrs_t octoclock_addrs; - //return an empty list of addresses when type is set to non-usrp2 + //return an empty list of addresses when type is set to non-OctoClock if (hint.has_key("type") and hint["type"].find("octoclock") == std::string::npos) return octoclock_addrs; //Return an empty list of addresses when a resource is specified, @@ -127,11 +127,9 @@ device_addrs_t octoclock_find(const device_addr_t &hint){ const octoclock_packet_t *pkt_in = reinterpret_cast<octoclock_packet_t*>(octoclock_data); while(true){ - size_t len = udp_transport->recv(asio::buffer(octoclock_data), 2); + size_t len = udp_transport->recv(asio::buffer(octoclock_data)); if(UHD_OCTOCLOCK_PACKET_MATCHES(OCTOCLOCK_QUERY_ACK, pkt_out, pkt_in, len)){ device_addr_t new_addr; - new_addr["type"] = (pkt_in->proto_ver == OCTOCLOCK_FW_COMPAT_NUM) ? "octoclock" - : "octoclock-bootloader"; new_addr["addr"] = udp_transport->get_recv_addr(); //Attempt direct communication with OctoClock @@ -143,9 +141,12 @@ device_addrs_t octoclock_find(const device_addr_t &hint){ 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){ + new_addr["type"] = "octoclock-bootloader"; octoclock_addrs.push_back(new_addr); } else{ + new_addr["type"] = "octoclock"; + octoclock_eeprom_t oc_eeprom(ctrl_xport); new_addr["name"] = oc_eeprom["name"]; new_addr["serial"] = oc_eeprom["serial"]; diff --git a/host/utils/octoclock_firmware_burner.cpp b/host/utils/octoclock_firmware_burner.cpp index bc91f22f9..9551ddd20 100644 --- a/host/utils/octoclock_firmware_burner.cpp +++ b/host/utils/octoclock_firmware_burner.cpp @@ -93,7 +93,7 @@ void list_octoclocks(){ * Manually find bootloader. This sends multiple packets in order to increase chances of getting * bootloader before it switches to the application. */ -device_addrs_t bootloader_find(std::string ip_addr){ +device_addrs_t bootloader_find(const std::string &ip_addr){ udp_simple::sptr udp_transport = udp_simple::make_connected(ip_addr, BOOST_STRINGIZE(OCTOCLOCK_UDP_CTRL_PORT)); octoclock_packet_t pkt_out; @@ -156,7 +156,9 @@ void burn_firmware(udp_simple::sptr udp_transport){ pkt_out.code = FILE_TRANSFER_CMD; //Actual burning below + size_t num_tries = 0; for(size_t i = 0; i < num_blocks; i++){ + num_tries = 0; pkt_out.sequence++; pkt_out.addr = i*BLOCK_SIZE; std::cout << "\r * Progress: " << int(double(i)/double(num_blocks)*100) @@ -164,8 +166,20 @@ void burn_firmware(udp_simple::sptr udp_transport){ memset(pkt_out.data, 0, BLOCK_SIZE); memcpy((void*)(pkt_out.data), &firmware_image[i*BLOCK_SIZE], std::min(int(firmware_size-current_pos), BLOCK_SIZE)); - UHD_OCTOCLOCK_SEND_AND_RECV(udp_transport, FILE_TRANSFER_CMD, pkt_out, len, octoclock_data); - if(not (UHD_OCTOCLOCK_PACKET_MATCHES(FILE_TRANSFER_ACK, pkt_out, pkt_in, len))){ + + bool success = false; + while(num_tries <= 5){ + UHD_OCTOCLOCK_SEND_AND_RECV(udp_transport, FILE_TRANSFER_CMD, pkt_out, len, octoclock_data); + if(UHD_OCTOCLOCK_PACKET_MATCHES(FILE_TRANSFER_ACK, pkt_out, pkt_in, len)){ + success = true; + break; + } + else{ + num_tries++; + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + } + if(not success){ std::cout << std::endl; throw uhd::runtime_error("Failed to burn firmware to OctoClock!"); } @@ -182,7 +196,6 @@ void verify_firmware(udp_simple::sptr udp_transport){ pkt_out.sequence = uhd::htonx<boost::uint32_t>(std::rand()); size_t len = 0, current_pos = 0; - std::cout << "Verifying firmware." << std::endl; for(size_t i = 0; i < num_blocks; i++){ pkt_out.sequence++; @@ -207,7 +220,7 @@ void verify_firmware(udp_simple::sptr udp_transport){ std::cout << "\r * Progress: 100% (" << num_blocks << "/" << num_blocks << " blocks)" << std::endl; } -void reset_octoclock(const std::string &ip_addr){ +bool reset_octoclock(const std::string &ip_addr){ udp_simple::sptr udp_transport = udp_simple::make_connected(ip_addr, BOOST_STRINGIZE(OCTOCLOCK_UDP_CTRL_PORT)); octoclock_packet_t pkt_out; @@ -215,8 +228,13 @@ void reset_octoclock(const std::string &ip_addr){ size_t len; UHD_OCTOCLOCK_SEND_AND_RECV(udp_transport, RESET_CMD, pkt_out, len, octoclock_data); - if(UHD_OCTOCLOCK_PACKET_MATCHES(RESET_ACK, pkt_out, pkt_in, len)) std::cout << "done." << std::endl; - else throw uhd::runtime_error("Failed to place device in state to receive firmware."); + if(not UHD_OCTOCLOCK_PACKET_MATCHES(RESET_ACK, pkt_out, pkt_in, len)){ + std::cout << std::endl; + throw uhd::runtime_error("Failed to place device in state to receive firmware."); + } + + boost::this_thread::sleep(boost::posix_time::milliseconds(3000)); + return (bootloader_find(ip_addr).size() == 1); } void finalize(udp_simple::sptr udp_transport){ @@ -225,10 +243,11 @@ void finalize(udp_simple::sptr udp_transport){ pkt_out.sequence = uhd::htonx<boost::uint32_t>(std::rand()); size_t len = 0; - std::cout << std::endl << "Telling OctoClock to load application..." << std::flush; UHD_OCTOCLOCK_SEND_AND_RECV(udp_transport, FINALIZE_BURNING_CMD, pkt_out, len, octoclock_data); - if(UHD_OCTOCLOCK_PACKET_MATCHES(FINALIZE_BURNING_ACK, pkt_out, pkt_in, len)) std::cout << "done." << std::endl; - else std::cout << "no ACK. Device may not have loaded application." << std::endl; + if(not UHD_OCTOCLOCK_PACKET_MATCHES(FINALIZE_BURNING_ACK, pkt_out, pkt_in, len)){ + std::cout << std::endl; + std::cout << "no ACK. Bootloader may not have loaded application." << std::endl; + } } int UHD_SAFE_MAIN(int argc, char *argv[]){ @@ -303,21 +322,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << std::endl << boost::format("Searching for OctoClock with IP address %s...") % ip_addr << std::flush; device_addrs_t octoclocks = device::find(str(boost::format("addr=%s") % ip_addr), device::CLOCK); if(octoclocks.size() == 1){ - //If in application, quietly reset into bootloader and try to find again if(octoclocks[0]["type"] == "octoclock"){ - reset_octoclock(ip_addr); - boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); - octoclocks = bootloader_find(ip_addr); - if(octoclocks.size() == 1) std::cout << "found." << std::endl; + std::cout << "found. Resetting..." << std::flush; + if(reset_octoclock(ip_addr)) std::cout << "successful." << std::endl; else{ - std::cout << std::endl; - throw uhd::runtime_error("Could not find OctoClock with given IP address!"); + std::cout << "failed." << std::endl; + throw uhd::runtime_error("Failed to reset OctoClock device into its bootloader."); } } else std::cout << "found." << std::endl; } else{ - std::cout << std::endl; + std::cout << "failed." << std::endl; throw uhd::runtime_error("Could not find OctoClock with given IP address!"); } @@ -326,11 +342,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::signal(SIGINT, &sig_int_handler); burn_firmware(udp_transport); + std::cout << "Verifying firmware." << std::endl; verify_firmware(udp_transport); + std::cout << std::endl << "Telling OctoClock bootloader to load application..." << std::flush; finalize(udp_transport); + std::cout << "done." << std::endl; std::cout << "Waiting for OctoClock to reinitialize..." << std::flush; - boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); + boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); octoclocks = device::find(str(boost::format("addr=%s") % ip_addr), device::CLOCK); if(octoclocks.size() == 1){ if(octoclocks[0]["type"] == "octoclock-bootloader"){ |