/****************************************************************************** * * Title : commandFunc_busTest.c * Version 0.0 * * Description: Data and address bus test. * * * Author: Lukas Tomasek, tomasekl@fzu.cz * ******************************************************************************/ /****************************************************************************** * Header files * ******************************************************************************/ #include #include #include #include "commandListDefinitions.h" #include "commandFunc_busTest.h" #include "commandParamsUir.h" #include "globalDefinitions.h" #include "uirUtility.h" #include "commandStatusMessage.h" #include "vmeHpiUtility.h" #include "mainUir.h" #include "RWlists.h" /****************************************************************************** * Definitions * ******************************************************************************/ #define CONST_DATA_SAMPLES 4 /* number of constant data tests */ /****************************************************************************** * Static Function Declarations * ******************************************************************************/ static ERROR_ID registerTest(UINT32 dataMask, UINT32 regAddress, UINT32 testData, int latchRegisterOn, UINT32 latchRegAddr, struct HOST *host); static UINT32 sqr(UINT32 base, UINT32 exponent); /****************************************************************************** * Global functions * ******************************************************************************/ /*============================================================================= * commandFunction_busTest() *============================================================================= * * After each register is tested separately with "flying 1", constant and random data, * all registers(still holding the last random data) are read out and data compared again. * */ ERROR_ID commandFunction_busTest(COMMAND_FUNC_OPTION funcOption, struct COMMAND *command, UINT8 slotNumber, FILE *file){ struct HOST *host; const int panel=global.panel.commandEdit[BUS_TEST_ID]; struct BUS_TEST_PARAMS *busTest=&command->params.busTest; int status, option; ERROR_ID errorId=SUCCESS; UINT32 dataMask; UINT32 regAddress; UINT32 testData; int i; int addressIndex; unsigned int fileSize; char inputText[500]; /* constant data test values */ const UINT32 constDataSamples[CONST_DATA_SAMPLES]={ 0x0, 0xFFFFFFFF, 0x55555555, 0xAAAAAAAA}; UINT32 *randomDataSamples; /* array storing the last random value written to each register */ UINT32 *testRegsAddr; /* array with addresses of the registers for test */ int numRegisters=0; UINT32 readData; switch(funcOption){ case COMMAND_TO_LIST: GetCtrlVal(panel, BUS_TEST_ONE_REG, &busTest->oneRegisterNotSet); GetCtrlVal(panel, BUS_TEST_DATA_WIDTH, &busTest->dataWidthInBits); GetCtrlVal(panel, BUS_TEST_ADDR_TEST_OPTION, &busTest->latchRegisterOn); GetCtrlVal(panel, BUS_TEST_ADDR_REG, &busTest->latchRegAddr); GetCtrlVal(panel, BUS_TEST_FLOAT_ONE, &busTest->floating1TestOnly); if(busTest->oneRegisterNotSet){ GetCtrlVal(panel, BUS_TEST_REG_ADDR, &busTest->regAddress); }else{ GetCtrlVal(panel, BUS_TEST_REG_ADDR_FILE, busTest->regsAddrFile); if(busTest->regsAddrFile[0]==0) { status = MessagePopup ("WARNING", "No RegsAddrFile selected!!"); UIR_STATUS_CHECK(status, MessagePopup()); return(PROGRAM_WARNING); } } break; case LIST_TO_COMMAND: SetCtrlVal(panel, BUS_TEST_ONE_REG, busTest->oneRegisterNotSet); SetCtrlVal(panel, BUS_TEST_DATA_WIDTH, busTest->dataWidthInBits); SetCtrlVal(panel, BUS_TEST_ADDR_TEST_OPTION, busTest->latchRegisterOn); SetCtrlVal(panel, BUS_TEST_ADDR_REG, busTest->latchRegAddr); status=SetInputMode(panel, BUS_TEST_ADDR_REG, busTest->latchRegisterOn); UIR_STATUS_CHECK(status, SetInputMode()); if(busTest->oneRegisterNotSet){ SetCtrlVal(panel, BUS_TEST_REG_ADDR, busTest->regAddress); }else{ SetCtrlVal(panel, BUS_TEST_REG_ADDR_FILE, busTest->regsAddrFile); } status=SetInputMode(panel, BUS_TEST_REG_ADDR, busTest->oneRegisterNotSet); UIR_STATUS_CHECK(status, SetInputMode()); status=SetInputMode(panel, BUS_TEST_REG_ADDR_FILE, !busTest->oneRegisterNotSet); UIR_STATUS_CHECK(status, SetInputMode()); SetCtrlVal(panel, BUS_TEST_FLOAT_ONE, busTest->floating1TestOnly); break; case COMMAND_EXECUTION: host=global.host[HOST_INDEX(slotNumber)]; errorId=setHpicMaster(host->slotNumber); HOST_ERROR_CHECK(errorId, host, setHpicMaster()); if(errorId!=SUCCESS) return(COMMAND_ERROR); /* init random numbers generator */ srand((unsigned int)time(NULL)); dataMask=sqr(2, busTest->dataWidthInBits)-1; if(busTest->oneRegisterNotSet){ numRegisters=1; }else{ errorId=getFileSize(busTest->regsAddrFile, &fileSize); HOST_ERROR_CHECK(errorId, host, getFileSize()); if(errorId!=SUCCESS){ sprintf(inputText,"##BUS TEST - cannot read RegsAddressFile(%s)!!\n",busTest->regsAddrFile); errorId=commandStatusMessage(host, host->commandStatusFile, inputText); HOST_ERROR_CHECK(errorId, host, commandStatusMessage()); return(COMMAND_ERROR); } if(fileSize%4){ errorId=commandStatusMessage(host, host->commandStatusFile,"##BUS TEST - RegsAddressFileSize not aligned on 4B boundary!!\n"); HOST_ERROR_CHECK(errorId, host, commandStatusMessage()); return(COMMAND_ERROR); } if(fileSize<4){ errorId=commandStatusMessage(host, host->commandStatusFile,"##BUS TEST - RegsAddressFileSize<4B!!\n"); HOST_ERROR_CHECK(errorId, host, commandStatusMessage()); return(COMMAND_ERROR); } numRegisters=fileSize/sizeof(UINT32); } testRegsAddr=calloc(numRegisters, sizeof(UINT32)); if(testRegsAddr==NULL){ HOST_ERROR_CHECK(PROGRAM_ERROR, host, calloc()); return(PROGRAM_ERROR); } randomDataSamples=calloc(numRegisters, sizeof(UINT32)); if(randomDataSamples==NULL){ HOST_ERROR_CHECK(PROGRAM_ERROR, host, calloc()); free(testRegsAddr); return(PROGRAM_ERROR); } if(busTest->oneRegisterNotSet){ testRegsAddr[0]=busTest->regAddress; }else{ /* fill testRegsAddr array */ errorId=readFromBinFile(busTest->regsAddrFile, testRegsAddr, fileSize); HOST_ERROR_CHECK(errorId, host, readFromBinFile()); if(errorId!=SUCCESS){ free(testRegsAddr); free(randomDataSamples); return(COMMAND_ERROR); } } for(addressIndex=0; addressIndexdataWidthInBits; ++i){ testData=1<latchRegisterOn, busTest->latchRegAddr, host); HOST_ERROR_CHECK(errorId, host, registerTest()); if(errorId!=SUCCESS){ free(testRegsAddr); free(randomDataSamples); return(COMMAND_ERROR); } } if(busTest->floating1TestOnly==0){ /* const data test */ for(i=0; ilatchRegisterOn, busTest->latchRegAddr, host); HOST_ERROR_CHECK(errorId, host, registerTest()); if(errorId!=SUCCESS){ free(testRegsAddr); free(randomDataSamples); return(COMMAND_ERROR); } } /* random data test */ testData=((rand()<<16)+rand())&dataMask; randomDataSamples[addressIndex]=testData; errorId=registerTest(dataMask, regAddress, testData, busTest->latchRegisterOn, busTest->latchRegAddr, host); HOST_ERROR_CHECK(errorId, host, registerTest()); if(errorId!=SUCCESS){ free(testRegsAddr); free(randomDataSamples); return(COMMAND_ERROR); } } } if(busTest->floating1TestOnly==0){ for(addressIndex=0; addressIndexslotNumber, regAddress, &readData, 1, NO_HPIA_AUTOINCREMENT, 0); HOST_ERROR_CHECK(errorId, host, RWmaster()); readData&=dataMask; if(readData!=testData){ sprintf(inputText,"##BUS TEST - RANDOM DATA ERROR - RegAddress: 0x%X, DataWritten: 0x%X, read: 0x%X !!\n", regAddress, testData, readData); errorId=commandStatusMessage(host, host->commandStatusFile, inputText); HOST_ERROR_CHECK(errorId, host, commandStatusMessage()); free(testRegsAddr); free(randomDataSamples); return(COMMAND_ERROR); } } } free(testRegsAddr); free(randomDataSamples); break; case SAVE_CMD_TO_FILE: fprintf(file, "oneRegisterNotSet= %d, regAddress= 0x%X, dataWidthInBits= %d,\nlatchRegisterOn= %d, latchRegAddr= 0x%X, floating1TestOnly= %d\n", busTest->oneRegisterNotSet, busTest->regAddress, busTest->dataWidthInBits, busTest->latchRegisterOn, busTest->latchRegAddr, busTest->floating1TestOnly); fprintf(file, "regsAddrFile[]= %s\n", busTest->regsAddrFile); break; case LOAD_CMD_FROM_FILE: status=fscanf(file, "oneRegisterNotSet= %d, regAddress= 0x%X, dataWidthInBits= %d,\nlatchRegisterOn= %d, latchRegAddr= 0x%X, floating1TestOnly= %d\n", &busTest->oneRegisterNotSet, &busTest->regAddress, &busTest->dataWidthInBits, &busTest->latchRegisterOn, &busTest->latchRegAddr, &busTest->floating1TestOnly); if(status==-1) {ERROR_CHECK(FATAL_ERROR, Read from cmd file error!); return(FATAL_ERROR);} status=readLineFromIndex(file, strlen("regsAddrFile[]= "), PATHNAME_LENGTH, busTest->regsAddrFile); if(status!=0) {ERROR_CHECK(FATAL_ERROR, Read from cmd file error!); return(FATAL_ERROR);} break; default: ; } return(SUCCESS); } /****************************************************************************** * Static functions * ******************************************************************************/ /*============================================================================= * registerTest() *============================================================================= * * * */ static ERROR_ID registerTest(UINT32 dataMask, UINT32 regAddress, UINT32 testData, int latchRegisterOn, UINT32 latchRegAddr, struct HOST *host){ UINT32 readData; ERROR_ID errorId; char inputText[500]; /* write test data to register */ errorId=RWmaster(WRITE, host->slotNumber, regAddress, &testData, 1, NO_HPIA_AUTOINCREMENT, 0); HOST_ERROR_CHECK(errorId, host, RWmaster()); /* check address in address latch register (if any) */ if(latchRegisterOn){ errorId=RWmaster(READ, host->slotNumber, latchRegAddr, &readData, 1, NO_HPIA_AUTOINCREMENT, 0); HOST_ERROR_CHECK(errorId, host, RWmaster()); if(readData!=regAddress){ sprintf(inputText,"##BUS TEST - ADDRESS ERROR - addrLatchRegData: 0x%X, expect: 0x%X !!\n", readData, regAddress); errorId=commandStatusMessage(host, host->commandStatusFile, inputText); HOST_ERROR_CHECK(errorId, host, commandStatusMessage()); return(COMMAND_ERROR); } } /* compare data */ errorId=RWmaster(READ, host->slotNumber, regAddress, &readData, 1, NO_HPIA_AUTOINCREMENT, 0); HOST_ERROR_CHECK(errorId, host, RWmaster()); readData&=dataMask; if(readData!=testData){ sprintf(inputText,"##BUS TEST - DATA ERROR - RegAddress: 0x%X, DataWritten: 0x%X, read: 0x%X !!\n", regAddress, testData, readData); errorId=commandStatusMessage(host, host->commandStatusFile, inputText); HOST_ERROR_CHECK(errorId, host, commandStatusMessage()); return(COMMAND_ERROR); } return(SUCCESS); } /*============================================================================= * sqr() *============================================================================= * * returns base^exponent * */ static UINT32 sqr(UINT32 base, UINT32 exponent){ UINT32 i, result; for(i=0, result=1; i