aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorNicholas Corgan <nick.corgan@ettus.com>2014-08-15 12:57:10 -0700
committerNicholas Corgan <nick.corgan@ettus.com>2014-08-20 09:42:26 -0700
commit2de96cd57c3f19bfa778ccad280ad19170af0967 (patch)
tree88e5235bbbc1df0dd5d6ce1883203a09f3e07ea3 /host
parent9fb6c2919ad9e7e736c837186861b362ba80cdfa (diff)
downloaduhd-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.cpp9
-rw-r--r--host/utils/octoclock_firmware_burner.cpp57
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"){