diff --git a/src/fw_downloader/fw_downloader.cpp b/src/fw_downloader/fw_downloader.cpp index 82ed684111d60fb33a57fc1d6cb77e4828775cec..0387134c8677131678bbef93dfddd54d792f0270 100755 --- a/src/fw_downloader/fw_downloader.cpp +++ b/src/fw_downloader/fw_downloader.cpp @@ -25,13 +25,14 @@ void show_help(char *name) std::cout << "Usage: " << name << "-d <serial device> -f <firmware file> -p <protocol> [-h]" << std::endl; std::cout << " -d serial_device Linux serial device used to communicate" << std::endl; std::cout << " -f firmware_file desired firmware file in Intel Hex format" << std::endl; - std::cout << " -p protocol Communication protocol to be used (original or new)" << std::endl; + std::cout << " -p protocol Communication protocol to be used" << std::endl; std::cout << " devices supported by the original protocol:" << std::endl; - std::cout << " - ax servo family" << std::endl; - std::cout << " - rx servo family" << std::endl; + std::cout << " - ax - for the AX servo family" << std::endl; + std::cout << " - rx - for the RX servo family" << std::endl; std::cout << " devices supported by the new protocol:" << std::endl; - std::cout << " - cm510" << std::endl; - std::cout << " - mx servo family" << std::endl; + std::cout << " - cm510 - for the CM510 controller" << std::endl; + std::cout << " - mx - for the MX servo family" << std::endl; + std::cout << " - cm730 - for the cm730 controller" << std::endl; std::cout << " -c clear eeprom memory" << std::endl; std::cout << " -r eeprom_file read eeprom memory to file" << std::endl; std::cout << " -h shows this help" << std::endl; @@ -48,13 +49,17 @@ int main(int argc,char *argv[]) bool end=false; int option; std::string opt_device,opt_fw_file,eeprom_file; + std::string device; protocol_t protocol; // binary file variables unsigned char binary_file[MEMORY_MAXSIZE]; long int downloaded_size=0; long int start_address=0; long int binary_size=0; + long int written_size=0; + long int write_size=0; int block_size=0,count=0; + std::stringstream base_address; // bootloader variables unsigned char bootloader_data[MEMORY_MAXSIZE]; bool bootloader_connected=false; @@ -93,10 +98,16 @@ int main(int argc,char *argv[]) break; case 'p':// select protocol std::cout << "Selected protocol: " << optarg << std::endl; - if(std::string(optarg)=="original") + if(std::string(optarg)=="ax" || std::string(optarg)=="rx") + { protocol=original_protocol; - else if(std::string(optarg)=="new") - protocol=new_protocol; + device=optarg; + } + else if(std::string(optarg)=="cm510" || std::string(optarg)=="mx" || std::string(optarg)=="cm730") + { + protocol=new_protocol; + device=optarg; + } else { std::cout << "Unsupported protocol" << std::endl; @@ -209,59 +220,74 @@ int main(int argc,char *argv[]) } } // start the download - serial_port.write((unsigned char *)&bootloader_load,1); - if(protocol==new_protocol) - serial_port.write((unsigned char *)&bootloader_ack,1); - end=false; - while(!end) - { - try{ - if((num_data=serial_port.get_num_data()==0)) - event_server->wait_all(events,300); - num_data=serial_port.get_num_data(); - serial_port.read(bootloader_data,num_data); - bootloader_data[num_data]='\0'; - printf("%s",bootloader_data); + do{ + base_address.str(""); + if(device=="cm730" || device=="mx") + base_address << "l " << std::hex << 0x08003000 + written_size << std::endl; + else + base_address << "l" << std::endl; + serial_port.write((unsigned char *)base_address.str().c_str(),base_address.str().size()-1); + if(protocol==new_protocol) + serial_port.write((unsigned char *)&bootloader_ack,1); + end=false; + while(!end) + { + try{ + if((num_data=serial_port.get_num_data()==0)) + event_server->wait_all(events,300); + num_data=serial_port.get_num_data(); + serial_port.read(bootloader_data,num_data); + bootloader_data[num_data]='\0'; + printf("%s",bootloader_data); + fflush(stdout); + }catch(CEventTimeoutException &e){ + end=true; + } + } + if((binary_size-written_size)>1024*20) + write_size=1024*20; + else + write_size=binary_size-written_size; + // compute the binary file checksum + checksum=0; + for(i=0;i<write_size;i++) + checksum+=binary_file[start_address+i]; + // send the binary file in 64 byte segments + while(downloaded_size < write_size) + { + usleep(1000); + block_size=write_size-downloaded_size; + if(block_size>64) + block_size=64; + serial_port.write(&binary_file[start_address+downloaded_size],block_size); + downloaded_size+=block_size; + printf("\rDownloading Firmware (%ld/%ld byte)", downloaded_size, write_size); fflush(stdout); - }catch(CEventTimeoutException &e){ - end=true; } - } - // compute the binary file checksum - for(i=0;i<binary_size;i++) - checksum+=binary_file[start_address+i]; - // send the binary file in 64 byte segments - while(downloaded_size < binary_size) - { usleep(1000); - block_size=binary_size-downloaded_size; - if(block_size>64) - block_size=64; - serial_port.write(&binary_file[start_address+downloaded_size],block_size); - downloaded_size+=block_size; - printf("\rDownloading Firmware (%ld/%ld byte)", downloaded_size, binary_size); - fflush(stdout); - } - usleep(1000); - // send the checksum - serial_port.write(&checksum,1); - std::cout << std::endl << "Download complete" << std::endl; - end=false; - while(!end) - { - try{ - if((num_data=serial_port.get_num_data()==0)) - event_server->wait_all(events,300); - // there has been an error - num_data=serial_port.get_num_data(); - serial_port.read(bootloader_data,num_data); - bootloader_data[num_data]='\0'; - printf("%s",bootloader_data); - }catch(CEventTimeoutException &e){ - // no error to report - end=true; + // send the checksum + serial_port.write(&checksum,1); + end=false; + while(!end) + { + try{ + if((num_data=serial_port.get_num_data()==0)) + event_server->wait_all(events,300); + // there has been an error + num_data=serial_port.get_num_data(); + serial_port.read(bootloader_data,num_data); + bootloader_data[num_data]='\0'; + printf("%s",bootloader_data); + }catch(CEventTimeoutException &e){ + // no error to report + end=true; + } } - } + written_size+=write_size; + start_address+=write_size; + downloaded_size=0; + }while(written_size<binary_size); + std::cout << std::endl << "Download complete" << std::endl; } } else if(read_eeprom) @@ -359,22 +385,25 @@ int main(int argc,char *argv[]) } } // go to application mode - serial_port.write((unsigned char *)&bootloader_app,1); - if(protocol==new_protocol) - serial_port.write((unsigned char *)&bootloader_ack,1); - end=false; - while(!end) + if(device=="ax") { - try{ - event_server->wait_all(events,300); - // there has been an error - num_data=serial_port.get_num_data(); - serial_port.read(bootloader_data,num_data); - bootloader_data[num_data]='\0'; - printf("%s",bootloader_data); - }catch(CEventTimeoutException &e){ - // no error to report - end=true; + serial_port.write((unsigned char *)&bootloader_app,1); + if(protocol==new_protocol) + serial_port.write((unsigned char *)&bootloader_ack,1); + end=false; + while(!end) + { + try{ + event_server->wait_all(events,300); + // there has been an error + num_data=serial_port.get_num_data(); + serial_port.read(bootloader_data,num_data); + bootloader_data[num_data]='\0'; + printf("%s",bootloader_data); + }catch(CEventTimeoutException &e){ + // no error to report + end=true; + } } } // start the loaded program