#include #include #include #include #include #include #include #include "gluex_newCanlib_debug.h" #include #include #include #include #include #include #include #include #include "includeAnaGate/AnaGateDllCan.h" //--------------------------------------------------- // Global variables needed to handle messages from AnaGate // device. unsigned char wAddr = 0; unsigned char rAddr = 0; unsigned int jz_timeout_count=0; int m_MessageBuffer[266][11]; //0 is ID, 1 is Message Length, 2-9 is 8(max) integers of data. //--------------------------------------------------- void clearBuffer() { rAddr = 0; wAddr = 0; for(int i = 0; i < 256; i++) { m_MessageBuffer[i][0] = 0; m_MessageBuffer[i][1] = 0; m_MessageBuffer[i][2] = 0; m_MessageBuffer[i][3] = 0; m_MessageBuffer[i][4] = 0; } } //------ DEBUG GLOGBAL VARIABLES ----- int TOcount = 0; //Number of Timeouts programming bases int NACKcount = 0; //Number of NACKS (Bad Responses) programming bases int FailureFlag = 0; int badID = 0; //------------------- void WriteMessage( Message& mess, Device& dev, fstream* outFile ){ /* Send a message over the bus. mess = message to send dev = handle for device */ #ifdef ANAGATE int nFlag = 0x01; // bit 0 => extended ID, bit 1 => remote telegram int id = mess.getID(); const int nData = (const int)mess.getNData(); int *data = mess.getData(); //char dataChar[nData]; char *dataChar = (char*)malloc(nData*sizeof(char)); for(int i=0; i 100){ //time_t rawtime; //time (&rawtime); //*outFile << "ExtraTime:\t" << ctime (&rawtime); for(int i = 101; i < wAddr+1; i++){ time_t rawtime; time (&rawtime); *outFile<<"Extra:\t" < 2) { cout<<"TIMEOUT"<setID( m_MessageBuffer[rAddr][0] ); recMess->setNData( m_MessageBuffer[rAddr][1] ); recMess->setData( &data[0] ); //cout<setID( (int)readMsg.ID ); recMess->setNData( (int)( readMsg.LEN & 0x000000FF )); recMess->setData( &data[0] ); } #endif return recMess; } //----------------------------------------------- #ifdef ANAGATE void WINAPI ReadCANMessage(int nIdentifier, const char * pcBuffer, int nBufferLen, int nFlags, int hHandle ) { /* Call back function needed to read messages from the AnaGate device. When AnaGate device receives a message, this function should be called. */ for( int i=0; igetHandle(), ReadCANMessage ); return dev; #else HANDLE h; unsigned int wBTR0BTR1 = 0x472F; // bit rate 50kB/s char *szDevNode = "/dev/pcan32"; // device mount point h = LINUX_CAN_Open( szDevNode, O_RDWR ); if( h == NULL ){ cout << "Couldn't open USB device..." << endl; cout << "\tFirst check the dongle is connected, then check " ; cout << "the device permissions." << endl; return NULL; } // A cout line is needed after opening the device // otherwise program hangs. cout << "Opened USB-Linux device... " << endl; CAN_Status( h ); // initialise comm... bit rate 50kB/s, extended message id int error_no = CAN_Init( h, wBTR0BTR1, CAN_INIT_TYPE_EX ); if( error_no ) { u32_t status = CAN_Status( h ); cerr << "Status: " << status < red = 0x01 => green = 0x02 => off */ // set up data field: int data[] = { RLED_INIT, color }; Message mess( id, &data[0], 2 ); WriteMessage( mess, dev ); } //---------------------------------------------------------- void getID(Device &dev, int id, int nReplies){ /* Sends a CAN message to all bases on the bus asking them to send back their ID. id = base ID to address nBases = number of bases on the bus i.e. the number of replies that the program will wait for. */ int read1 = 0; vector id_vec; vector repeat_ids; // set up data field: int data[] = { ID_INIT }; int ndata = 1; Message mess( id, &data[0], ndata ); WriteMessage( mess, dev ); while( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); //cout << "board id: " << recMess->getID() << endl; //Check for any repeat IDs on device for(int it=0; itgetID()==id_vec[it]){ repeat_ids.push_back(recMess->getID()); } } //Print any repeats if(repeat_ids.size()>=1){ cout <<"WARNING!!!! The following CAN id's were seen multiple times, causing others to probably be missed!!!" << endl; for(int it=0; itgetID() << endl; cout << endl << "Board id: " << recMess->getID() << endl; cout << dec; int *recData = recMess->getData(); int HV_stat; HV_stat = recData[1]; cout << "HV status: " << HV_stat << endl; if((HV_stat & 0x40)==0x40) cout<<"ENBMVB = ON\n"; // ENBMVB STATUS else cout<<"ENBMVB = OFF\n"; if((HV_stat & 0x80)==0x80) cout<<"ENBMVT = ON\n"; // ENBMVT STATUS else cout<<"ENBMVT = OFF\n"; if((HV_stat & 0x10)==0x10) cout<<"ENBHVB = ON\n"; // ENBHVB STATS else cout<<"ENBHVB = OFF\n"; if((HV_stat & 0x04)==0x04) cout<<"ENBHVT = ON\n"; // ENBHVT STATUS else cout<<"ENBHVT = OFF\n"; if((HV_stat & 0x20)==0x20) cout<<"JAMHVB = ON\n"; // JAMHVB STATUS else cout<<"JAMHVB = OFF\n"; if((HV_stat & 0x08)==0x08) cout<<"JAMHVT = ON\n"; // JAMHVT STATUS else cout<<"JAMHVT = OFF\n"; delete recMess; read1++; } } } //---------------------------------------------------------- void SetVoltage(Device &dev, int id, float Voltage){ /* This sends a CAN message instructing the MCU to write a new value to the 12-bit DAC. id = base id to address Voltage = new voltage to set Voltage must be a float between 0 and 2047.5 12-bit DAC => takes input values 0-4096 1. Multiply Voltage by 2 and cast as integer => integer from 0-4096 i.e. a 12-bit number 2. Split this value into 8 most significant bits and 4 least significant bits, so that they can fit in the 8-bit CAN message data fields. 3. Send CAN message. */ int DAchannel; int value = (int)(Voltage*2.); DAchannel = value & 0x0000FFFF; // set up data field: int data[] = { DA_INIT, ((DAchannel>>4) & 0x0000FF), ((DAchannel<<4) & 0x0000F0) }; Message mess( id, &data[0], 3 ); WriteMessage( mess, dev ); //Debug Output Bytes //int dummy1 = (DAchannel>>4) & 0x000000FF; //int dummy2 = (DAchannel<<4) & 0x000000F0; //cout << "1st CAN byte: " << DA_INIT << endl; //cout << "2nd CAN byte: " << dummy1 << endl; //cout << "3rd CAN byte: " << dummy2 << endl; } //---------------------------------------------------------- void PowerDown(Device &dev, int id){ /* Function sends CAN message putting control board in low power mode id = id of base to address */ // set up data field: int data[] = { PD_INIT }; Message mess( id, &data[0], 1 ); WriteMessage( mess, dev ); } //---------------------------------------------------------- void PowerUp(Device &dev, int id){ /* Send a CAN message to MCU - triggers an interrupt in firmware which will wake it up from halt mode. */ // set up data field: int data[] = { PU_INIT }; Message mess( id, &data[0], 1 ); WriteMessage( mess, dev ); } //---------------------------------------------------------- void ADC( Device &dev, int id, int command, int nReplies ){ /* Read one of the ADCs. id = id of base to address command = ADC_MVB medium voltage (bottom) ADC_MVT medium voltage (top) ADC_DYN first dynode voltage ADC_CAT photocathod voltage ADC_DAC DAC voltage ADC_TEM temperature monitor ADC_CUR current monitor nReplies = number of replies to wait for The message sent back by the base contains the ADC value in channels, this function also calibrates that value into volts C or A. */ int i; // set up data field: int data[] = { ADC_INIT, command }; Message mess( id, &data[0], 3 ); WriteMessage( mess, dev ); uint8_t value0; uint8_t value1; uint8_t value2; uint8_t value3; uint8_t value4; uint8_t value5; uint8_t value6; int command_check; int read1 = 0; while ( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); read1++; int *recData = recMess->getData(); value0 = recData[0]; value1 = recData[1]; value2 = recData[2]; value3 = recData[3]; value4 = recData[4]; value5 = recData[5]; value6 = recData[6]; uint16_t my_variance = (value4 << 8) | (value5) ; double HV_correction = ((double)value6/(32.*1023.)) * 3.00 * 1000. ; command_check = recData[3]; int ADCchannels = (value1 << 8) | value2 ; float ADCvoltage = (float)ADCchannels; cout << "board id: " << recMess->getID() << endl; cout << dec; //cout << "Command base sent back was: 0x" <getData(); value0 = recData[1]; value1 = recData[2]; value6 = recData[6]; command_check = recData[3]; int ADCchannels = (value0 << 8) | value1 ; float ADCvoltage = (float)ADCchannels; //cout << "board id 0x" << hex << recMess->getID() << endl; //cout << dec; if(command == command_check) { if( command == ADC_CAT){ adc_type = "CAT"; ADCvoltage = (float)(ADCchannels/1023.) * 3.00 * 1000. + ((double)value6/(32.*1023.)) * 3.00 * 1000.; //cout<<"Photocathode voltage is " << ADCvoltage << " volts.\n"; //cout<<"The photocathode voltage in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else if(command == ADC_DYN){ adc_type = "DYN"; ADCvoltage = (float)(ADCchannels/1023.) * 3.00 * 1000.; //cout<<"1st dynode voltage is " << ADCvoltage << " volts.\n"; //cout<<"The 1st dynode voltage in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else if(command == ADC_MVT){ adc_type = "MVT"; ADCvoltage = (float)(ADCchannels/1023.)*3.00; //cout<<"Medium voltage (top) is " << ADCvoltage << " volts.\n"; //cout<<"The medium voltage (top) in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else if(command == ADC_MVB){ adc_type = "MVB"; ADCvoltage = (float)(ADCchannels/1023.)*3.00; //cout<<"Medium voltage (bottom) is " << ADCvoltage << " volts.\n"; //cout<<"The medium voltage (bottom) in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else if(command == ADC_TEM){ adc_type = "TEM"; ADCvoltage = (float)(ADCchannels/1023.)*3.00*100; //cout<<"Temperature is " << ADCvoltage << " C.\n"; //cout<<"The temperature monitor in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else if(command == ADC_CUR){ adc_type = "CUR"; ADCvoltage = (float)(ADCchannels/1023.)*3.00/200.; //cout<<"Current is " << ADCvoltage << " A.\n"; //cout<<"The current monitor in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else if(command == ADC_DAC){ adc_type = "DAC"; ADCvoltage = (float)(ADCchannels/1023.)*3.00; //cout<<"DAC voltage is " << ADCvoltage << " volts.\n"; //cout<<"The DAC voltage in ADC channels (0 - 1023) is: " << ADCchannels << endl; } else{ adc_type = "NoType"; //cout<<"The voltage in ADC channels (0 - 1023) is: " << ADCchannels << endl; } } else cout << "WARNING: Found a mismatch!!! Skipping... " << endl; //std::stringstream stream; //stream << "0x" << hex << recMess->getID(); //std::string result( stream.str() ); int my_id = (int) recMess->getID(); if (my_id==0) {cout << "Manny Found a TimeOut" << endl;} if (outFile!=NULL) *outFile << my_id << "\t" << adc_type << "\t" << ADCvoltage << endl; delete recMess; } } //---------------------------------------------------------- void CheckVersion( Device &dev, int id, int nReplies, string version_num ){ /* If version number passed to function does not match the version on the board then gives a cout statement */ // set up data field: int data[] = { VER_INIT }; Message mess( id, &data[0], 3 ); WriteMessage( mess, dev ); int read1 = 0; while( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); int read_id = recMess->getID(); int *recData = recMess->getData(); string base_firm = recData[1]+"."+recData[2]; if(base_firm != version_num) { cout << "Error: Base " << dec << read_id << " is running firmware " << base_firm << endl; } delete recMess; read1++; } return; } void ReadVersion( Device &dev, int id, int nReplies ){ /* Sends a CAN message out with identifier id. id = id of base to address; 0x00 to address all bases on bus nBases = number of bases on the bus i.e. the number of replies that the program will wait for. */ // set up data field: int data[] = { VER_INIT }; Message mess( id, &data[0], 3 ); WriteMessage( mess, dev ); int read1 = 0; while( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); int read_id = recMess->getID(); int *recData = recMess->getData(); cout << "board id " << read_id; cout << dec; cout << " is running firmware version " << recData[1]; cout << "." << recData[2] << endl; //cout << "Third bit is: " << hex << recData[3] << endl; for(int i = 0; i < 8; i++) cout<& retVals,bool break_on_error){ const int timedelay = 10000; int badStrand = 999; bool upload_success=true; int data[] = { IAP_INIT, 0x7F }; FILE* file1; file1 = fopen("BASEFIRMWARE.HEX","r"); char dummy1[50]; char dummy2[50]; vector StartingIDs = GetBaseIDs(dev,id,nReplies); vector BadIDs; Message mess( id, &data[0], 2); WriteMessage( mess, dev); ReceiveMsg(dev, id, nReplies); //If upload timed out, and you are re-entering with a non-zero linecount, you want to start //at line = linecount of BASEFIRMWARE.HEX, so do fscanf, linecount times, to get to the //line you were interrupted on if(linecount!=0) { for(int j = 0; j < linecount; j++) { fscanf(file1, "%s", &dummy1); } } for(int j = linecount; j < 10000; j++) { if(jz_timeout_count>=100) { cout << "Too many timeouts!!!! Quitting upload..." << endl; return 1; } badStrand = 999; FailureFlag = 0; if(j%100==0) cout<<"i: "<=100) { cout << "Too many timeouts!!!! Quitting clearing..." << endl; return; } FailureFlag = 0; if(i%100==0) cout<<"i: "<& retVals ){ int data[] = { STAT_INIT, STAT_READ }; Message mess( id, &data[0], 2 ); WriteMessage( mess, dev ); int status_value; int read1 = 0; int failCount = 0; vector id_vec; vector repeat_ids; bool repeat_flag=false; vector > bad_stat_ids; while ( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); read1++; int *recData = recMess->getData(); status_value = recData[0]; cout << "board id " << recMess->getID() << endl; if(recMess->getID()==0) failCount++; cout << dec; //check for bad status values if(status_value<0 || status_value>=3) bad_stat_ids.push_back(make_pair(recMess->getID(),status_value)); //Check for any repeat IDs on device for(int it=0; itgetID()==id_vec[it]) && (recMess->getID() != 0)) repeat_flag=true; } if(!repeat_flag) id_vec.push_back(recMess->getID()); if(repeat_flag) repeat_ids.push_back(recMess->getID()); repeat_flag=false; //done with checking cout<<"Status Value is " << status_value << "\n"; delete recMess; } //Print any repeated IDs if(repeat_ids.size()>=1){ cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; cout <<"WARNING!!!! The following CAN id's were seen multiple times, causing others to probably be missed!!!" << endl; cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; for(int it=0; it=1){ cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; cout << "WARNING!!! Unexpected status value!!!!" << endl; cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; for(int it=0; it my_pair = bad_stat_ids[it]; cout <<"ID: " << my_pair.first << " status value " << my_pair.second << endl; } } retVals.push_back(failCount); } void LightBad( Device &dev, int id, int nReplies,std::vector& retVals ){ jz_timeout_count=0; int data[] = { STAT_INIT, STAT_READ }; Message mess( id, &data[0], 2 ); WriteMessage( mess, dev ); int status_value; int read1 = 0; int failCount = 0; while ( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); read1++; int *recData = recMess->getData(); status_value = recData[0]; //cout << read1 << " board id " << recMess->getID() << endl; if(recMess->getID()!=0) retVals.push_back(recMess->getID()); //cout << dec; //cout<<"Status Value is " << status_value << "\n"; delete recMess; } } vector GetBaseIDs( Device &dev, int id, int nReplies){ int data[] = { STAT_INIT, STAT_READ }; std::vector retVals; int status_value; int read1 = 0; int failCount = 0; Message mess( id, &data[0], 2 ); WriteMessage( mess, dev ); while ( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); read1++; int *recData = recMess->getData(); status_value = recData[0]; //cout << "board id 0x" << hex << recMess->getID() << endl; if(recMess->getID()!=0) retVals.push_back(recMess->getID()); cout << dec; //cout<<"Status Value is " << status_value << "\n"; delete recMess; } return retVals; } void WriteStat( Device &dev, int id, int nReplies, int statByte){ int data[] = { STAT_INIT, STAT_WRITE, statByte }; Message mess( id, &data[0], 3 ); WriteMessage( mess, dev ); } void ReceiveMsg( Device &dev, int id, int nReplies){ int read1 = 0; if(jz_timeout_count>=100) { cout << "Too many timeouts!!! Exiting?" << endl; return; } while( read1 < nReplies ){ Message *recMess = ReadMessage( dev ); int read_id = recMess->getID(); int *recData = recMess->getData(); //cout << "board id 0x" << hex << read_id< "; if (recData[0] == 0x79) { //cout<<"GOOD\n"; } else { cout<<"ID: "< "; cout<<"BAD: "< initial, vector final){ for(unsigned int ii =0; ii < initial.size(); ++ii) { int initial_id = initial[ii]; bool found = false; for(unsigned int j=0; j