//2023.10.03 duepp program format research //2023.10.06 +due_download_prog() file output //2023.10.07 +int due_download_prog_save_to_file, +loop for {events} //10.18 +int due_download_prog_save_to_file_command/data //11.01 +serial //13.11.2023 + test program on real data //06.02.2023 + reading sync pulse sequence from csv file //22.05.2024 + added out stream to function due_upload_trajectory in serial_lib_cpp.cpp //25.05.2024 + added stream ability in serial_lib_cpp.cpp //digital pin 33 -> RF //digital pin 40 -> ADC //digital pin 5 -> RS485 converter direction //digital pin 6 -> GRU #include #include // for setbase(), works for base 8,10 and 16 only #include #include #include #include "serial_lib_cpp.cpp" #include #include #include #include #include #include #include "serialib.h" // Serial library #include "pugixml.hpp" #include "simplelogger.hpp" #define DEBUG_ENABLED using namespace std; using namespace std::literals::chrono_literals; //#define SERIAL_PORT "\\\\.\\COM1" //const string SERIAL_PORT{"\\\\.\\COM19"}; extern std::ostream out(std::cout.rdbuf()); extern SimpleLogger newlogger = SimpleLogger(out, "sync", "synclogs"); static bool en_cout = false; static bool en_debug = false; int32_t ii, jj, kk, nn, reps, maxnb; char ch; char buffer[255]; char dstr[1024]; uint8_t b[255]; uint32_t outputs1, outputs2, ticks1, ticks2; uint32_t outputs3, outputs4, ticks3, ticks4; uint32_t outputs5, outputs6, ticks5, ticks6; uint32_t outputs7, outputs8, ticks7, ticks8; uint32_t outputs9, outputs10, ticks9, ticks10; uint32_t outputs11, ticks11; /*uint32_t to_uint32_t(string param){ try{ uint32_t result = stod(param); if (result > 0){ return uint32_t(result); }}//try catch (std::invalid_argument const& ex){ newlogger << "XML parse error std::invalid_argument:: " << ex.what() <<" error in param: "<= 0){ return uint32_t(result); } else{ throw std::invalid_argument("Result isn't integer type\n"); } } bool CheckNode(string param, pugi::xml_node node) { if (node==nullptr) { newlogger << LogPref::Flag(ERROR) << "Parameter " << param << " not found"<< std::endl; return false; } if (strlen(node.text().get())==0) { newlogger << LogPref::Flag(ERROR) << "No text for parameter " << param << std::endl; return false; } // if(en_debug) // { // newlogger << LogPref::Flag(DEBUG) << "Showing parameter : " << param << std::endl; // newlogger << LogPref::Flag(DEBUG) << param << " get text: " << node.text().get() << std::endl; // newlogger << LogPref::Flag(DEBUG) << param << " get as int : " << to_uint32_t(node.text().get())<< std::endl; // } //newlogger << param << " get as double : " << node.text().as_double() << std::endl; //newlogger << param << " get as bool: " << node.text().as_bool() << std::endl; return true; } //function ShowParam } uint32_t GetOutputs(uint32_t RF, uint32_t SW, uint32_t ADC, uint32_t GRU){ std::stringstream debug_ss; uint32_t outputs{0x07080000}; switch(RF){ case 0: outputs = outputs&0xFFFFFFFE; debug_ss << "\nRF 0"<< endl; break; case 1: outputs = outputs|0x00000002; debug_ss << "\nRF 1"<< endl; break; }//end switch RF debug_ss << hex << outputs << endl; switch(SW){ case 0: outputs = outputs&0xFFFFFFEF; debug_ss << "SW 0" << endl; break; case 1: outputs = outputs|0x00000010; debug_ss << "SW 1" <>& vec){ // Handle input xml try { if (argc < 2) { throw std::invalid_argument("Incorrect number of arguments"); } newlogger << "Try to load file...\n"; pugi::xml_parse_result result = doc.load_file(argv[1]); if (!result) { throw std::invalid_argument("Error in loading file"); } } catch(const std::invalid_argument& e) { newlogger << LogPref::Flag(ERROR) << e.what() << std::endl; return 6; } newlogger << LogPref::Flag(OK) << "External XML structure is OK\n"; // Check, is this file stucture fits us uint32_t ParamCount = utilityFunctions::to_uint32_t(doc.child("root").child("ParamCount").text().get()); if(en_debug) newlogger << LogPref::Flag(DEBUG) << "ParamCount = " << ParamCount << std::endl; // Data arrays (vectors) std::vector RF_array; std::vector SW_array; std::vector ADC_array; std::vector GR_array; std::vector CL_array; try { for (size_t i = 1; i <= ParamCount; i++){ std::string param1 = "RF"+std::to_string(i); std::string param2 = "SW"+std::to_string(i); std::string param3 = "ADC"+std::to_string(i); std::string param4 = "GR"+std::to_string(i); std::string param7 = "CL"+std::to_string(i); // Find necessary tag and put variable in array RF_array.push_back(utilityFunctions::to_uint32_t(doc.child("root").child("RF").child(param1.c_str()).text().get())); SW_array.push_back(utilityFunctions::to_uint32_t(doc.child("root").child("SW").child(param2.c_str()).text().get())); ADC_array.push_back(utilityFunctions::to_uint32_t(doc.child("root").child("ADC").child(param3.c_str()).text().get())); GR_array.push_back(utilityFunctions::to_uint32_t(doc.child("root").child("GR").child(param4.c_str()).text().get())); CL_array.push_back(utilityFunctions::to_uint32_t(doc.child("root").child("CL").child(param7.c_str()).text().get())); // Condition for correctness if(!utilityFunctions::CheckNode(param1, doc.child("root").child("RF").child(param1.c_str())) || !utilityFunctions::CheckNode(param2, doc.child("root").child("SW").child(param2.c_str())) || !utilityFunctions::CheckNode(param3, doc.child("root").child("ADC").child(param3.c_str())) || !utilityFunctions::CheckNode(param4, doc.child("root").child("GR").child(param4.c_str())) || !utilityFunctions::CheckNode(param7, doc.child("root").child("CL").child(param7.c_str()))){ throw std::invalid_argument("Incorrect XML structure\n"); } } } catch(const std::invalid_argument& e){ newlogger << LogPref::Flag(ERROR) << e.what() << '\n'; return -5; } newlogger << LogPref::Flag(OK) << "Internal structure of XML is OK\n"; // Pushing arrays into return vector vec.push_back(RF_array); vec.push_back(SW_array); vec.push_back(ADC_array); vec.push_back(GR_array); vec.push_back(CL_array); //doc.save(std::cout); return 0; } // csv handler int evalCsv(int argc, char** argv, std::vector>& vec){ std::string filename = argv[1]; std::ifstream work_file(filename); std::string line; char delimiter = ','; uint32_t csv_row_counter = 0; uint32_t ticks{0}; std::vector RF_list; std::vector TR_SW_list; std::vector ADC_list; std::vector GRAD_R_list; std::vector CYCLES_NUM_list; while (getline(work_file, line)) { std::stringstream stream(line); std::string RF, TR_SW, ADC, GRAD_R, CYCLES_NUM, del_; std::getline(stream, RF, delimiter); std::getline(stream, TR_SW, delimiter); std::getline(stream, ADC, delimiter); std::getline(stream, GRAD_R, delimiter); std::getline(stream, CYCLES_NUM, delimiter); RF_list.push_back(stoi(RF)); TR_SW_list.push_back(stoi(TR_SW)); ADC_list.push_back(stoi(ADC)); GRAD_R_list.push_back(stoi(GRAD_R)); CYCLES_NUM_list.push_back(stoi(CYCLES_NUM)); std::cout << "==================" << '\n'; std::cout << "RF: " << RF << '\n'; std::cout << "TR_SW: " << TR_SW << '\n'; std::cout << "ADC: " << ADC << '\n'; std::cout << "GRAD_R: " << GRAD_R << '\n'; std::cout << "CYCLES_NUM: " << CYCLES_NUM<< '\n'; csv_row_counter += 1; ticks += stoi(CYCLES_NUM); } work_file.close(); // auto iter_rf = RF_list.begin(); // auto iter_tr_sw = TR_SW_list.begin(); // auto iter_adc = ADC_list.begin(); // auto iter_grad = GRAD_list.begin(); // auto iter_cycles = CYCLES_NUM_list.begin(); // for (int i=0; i)" << endl; return -1; } if(argc > 2) { for(int i = 2; i < argc; i++) { if(strcmp(argv[i], "--debug")==0) { en_debug = true; } else if(strcmp(argv[i], "--disable-console")==0) { newlogger.enableConsoleOutput(false); } else if(strcmp(argv[i], "-p")==0) { int nump = 1; if(i+1 < argc) { try { nump = stoi(argv[i+1], nullptr, 10); } catch(std::invalid_argument const& ex) { std::cout << "Invalid argument for serial port: " << ex.what() << std::endl; return -2; } catch(std::out_of_range const& ex) { std::cout << "Argument is out of range for serial port: " << ex.what() << std::endl; return -2; } SERIAL_PORT = std::string("\\\\.\\COM") + std::string(argv[i+1]); } } } } int status = INFO; // Default duepp debug string strcpy(dstr,"duepp: Everything is allright\n"); // READING SEQUENCE FILE pugi::xml_document doc; newlogger << "Start...\n"; std::string fileName = argv[1]; newlogger << "File: " << fileName << "\n"; size_t fileNameSize = fileName.size(); std::vector> returnmentValues; try { if(fileName.substr(fileNameSize - 3, 3) == "xml") { int r = evalXml(argc, argv, doc, returnmentValues); if(r != 0) { return r; } } else if(fileName.substr(fileNameSize - 3, 3) == "csv") { int r = evalCsv(argc, argv, returnmentValues); if(r != 0) { return r; } } else { throw std::invalid_argument("Incorrect file name or size\n"); } } catch(const std::invalid_argument& e){ newlogger << LogPref::Flag(ERROR) << e.what() << '\n'; return -5; } newlogger << LogPref::Flag(DONE) << "File loaded successfully\n"; uint32_t ParamCount = utilityFunctions::to_uint32_t(doc.child("root").child("ParamCount").text().get()); /*const string filepath{""}; const string filename{"sync_v2.xml"}; newlogger << filepath+filename << endl; pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file((filepath+filename).c_str()); newlogger << boolalpha << showpoint; //boolalpha and noboolalpha newlogger << "Load result: " << result.description() << std::endl; // CheckNode("noparam", doc.child("config").child("nochild") ); // CheckNode("param1", doc.child("config").child("param1") ); // CheckNode("param2", doc.child("config").child("param2") ); // CheckNode("param3", doc.child("config").child("param3") ); // CheckNode("param4", doc.child("config").child("param4") ); // CheckNode("param5", doc.child("config").child("param5") ); // CheckNode("param6", doc.child("config").child("param6") ); // // CheckNode("config2-param1", doc.child("config").child("config2").child("param1") ); newlogger<<"ParamCount = "; uint32_t ParamCount = to_uint32_t(doc.child("root").child("ParamCount").text().get()); newlogger<>0)&0xff); //// newlogger << "" << setbase(16) << std::setfill ('0') << std::setw(8)<< std::uppercase << program1.data[ii]<< endl; //newlogger<<"byte1 = "; ////newlogger<>8)&0xff); //newlogger<<"byte2 = " ; ////newlogger<