#include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include int MpodStatusParserDebug=0; static long MpodStatusParserInit(aSubRecord *precord) { // struct dbAddr *pAddr; // pAddr = (struct dbAddr*) calloc(2, sizeof(struct dbAddr)); // precord->dpvt = pAddr; if (MpodStatusParserDebug) printf("Record %s called MpodStatusParserInit(%p)\n", precord->name, (void*) precord); // dbNameToAddr((char*)(precord->inpa).value.constantStr, pAddr); // if (MpodStatusParserDebug) printf("Record %s called MpodStatusParserInit(%p)\n", (char*)(precord->inpa).value.constantStr, (void*) pAddr); // // ++pAddr; // access the nex element of array // dbNameToAddr((char*)(precord->inpb).value.constantStr, pAddr); // if (MpodStatusParserDebug) printf("Record %s called MpodStatusParserInit(%p)\n", (char*)(precord->inpb).value.constantStr, (void*) pAddr); return 0; } static long MpodStatusParserProcess(aSubRecord *precord) { if (MpodStatusParserDebug) printf("Record %s called MpodStatusParserProcess(%p)\n", precord->name, (void*) precord); // stat_string like this "80 01 C0 outputOn(0) 15 16 17" means "8001c0" is the number with bits 0 15 16 17 risen. // So the algorith will be to count number of all fields (7 in this case). Then read first tokens as numbers and count the number of bits risen. // For example 80 has 1 bit 01 has another 1 and c0 has 2 bits. In total 4 + 3 tokens (80,01,c0) = 7 number of tokens // This last condition would be the consistency check for our parser. char* stat_string = (char *)precord->a; char ststr[40]; char tmp[40]; const int MAX_VOLTAGE_STATUSES = 32; char* statuses[20] = {"On ", "Inhibit ", "FailureMinSenseVoltage ", "FailureMaxSenseVoltage ", "FailureMaxTerminalVoltage ", "FailureMaxCurrent ", "FailureMaxTemperature ", "FailureMaxPower ", "", "FailureTimeout ", "CurrentLimited ", "RampUp ", "RampDown ", "EnableKill ", "EmergencyOff ", "Adjusting ", "ConstantVoltage ", "VoltageBoundsExceeded ", "CurrentBoundsExceeded ", "FailureCurrentLimit" }; strncpy(ststr,stat_string,40); // calculate number of tokens in the string int ntokens = 0; while (sscanf(stat_string, " %s ", &tmp[0])==1 && ntokensa; // reset the pointer to original place if (MpodStatusParserDebug) printf("1) ntokens = %d, %s\n", ntokens, stat_string); // get number of bits read and compare with number of tokens for consistency uint8_t st[MAX_VOLTAGE_STATUSES]; // number status read unsigned char bits[MAX_VOLTAGE_STATUSES]; // bits memset(bits, 0xff, sizeof(bits)); int numbers=0, nbits=0; int j; uint32_t result = 0; if (sizeof(result)*8 != MAX_VOLTAGE_STATUSES) printf("WARNING::"__FILE__"::%d number of bits in the result must be = %d. Otherwise results are not guaranteed.\n",__LINE__, MAX_VOLTAGE_STATUSES); while (sscanf(stat_string, "%02x ", (unsigned int*)&st[numbers])==1 && numbersname, (char*)ststr); //// recGblSetSevr(precord, UDF_ALARM, INVALID_ALARM); //// return -1; // } if (MpodStatusParserDebug) { for(j=0; jname, precord->inpa.value.constantStr, result); } ((unsigned long *)(precord->vala))[0] = result; // mbbiDirect will keep the last 16 bits // output to bi record epicsEnum16 *outbi = (epicsEnum16*)precord->valb; if ( (result & 1<<0) && // GOOD outputOn (0), output channel is on !(result & 1<<1) && // BAD outputInhibit(1), external (hardware-)inhibit of the output channel //!(result & 1<<2) && // BAD outputFailureMinSenseVoltage (2) Supervision limit hurt: Sense voltage is too low !(result & 1<<3) && // BAD outputFailureMaxSenseVoltage (3), Supervision limit hurt: Sense voltage is too high !(result & 1<<4) && // BAD outputFailureMaxTerminalVoltage (4), Supervision limit hurt: Terminal voltage is too high !(result & 1<<5) && // BAD outputFailureMaxCurrent (5), Supervision limit hurt: Current is too high !(result & 1<<6) && // BAD outputFailureMaxTemperature (6), Supervision limit hurt: Heat sink temperature is too high !(result & 1<<7) && // BAD outputFailureMaxPower (7), Supervision limit hurt: Output power is too high !(result & 1<<9) && // BAD outputFailureTimeout (9), Communication timeout between output channel and main control // NORMAL outputCurrentLimited (10), Current limiting is active (constant current mode) // NORMAL outputRampUp (11), Output voltage is increasing (e.g. after switch on) // NORMAL outputRampDown (12), Output voltage is decreasing (e.g. after switch off) !(result & 1<<13) && // BAD outputEnableKill (13), EnableKill is active !(result & 1<<14) && // BAD outputEmergencyOff (14), EmergencyOff event is active // NORMAL outputAdjusting (15), Fine adjustment is working // NORMAL outputConstantVoltage (16), Voltage control (constant voltage mode) !(result & 1<<17) && // BAD outputVoltageBoundsExceeded (17), output Voltage out of bounds (outputLowCurrentRange) !(result & 1<<18) && // BAD outputCurrentBoundsExceeded (18), output Current out of bounds !(result & 1<<19) ) // BAD outputFailureCurrentLimit (19) Hardware current limit (EHS) / trip (EDS, EBS) was exceeded { outbi[0] = 1; // Good } else { outbi[0] = 0; // Not good } char *outstringin = (char*)precord->valc; int i, l = 0; if (result & 1<<0) { strcpy(outstringin, "On "); } else { strcpy(outstringin, "Off "); } // for(i = 1; i<20; i++){ for(i = 1; i<20; i++){ if (i==2) continue; // outputFailureMinSenseVoltage is masked if (i==15 || i==16) continue; // Cutted out the bits 15th and 16th bits l = 39 - strlen(outstringin); if (l > 0 && (result & 1<b; // printf("Record %s called MpodStatusParserProcess() AlarmStat = %d menuAlarmStatLINK = %d\n", precord->name, (int)aStat[0], menuAlarmStatLINK); // if (aStat[0] == menuAlarmStatLINK) strcpy(outstringin,"Unplugged"); if ( strlen(ststr) == 0 ) strcpy(outstringin,"Unplugged"); if (MpodStatusParserDebug) printf("Record %s called MpodStatusParserProcess(%s) before the end\n", precord->name, precord->inpa.value.constantStr); return 0; } // outputOn (0), output channel is on // outputInhibit(1), external (hardware-)inhibit of the output channel // outputFailureMinSenseVoltage (2) Supervision limit hurt: Sense voltage is too low // outputFailureMaxSenseVoltage (3), Supervision limit hurt: Sense voltage is too high // outputFailureMaxTerminalVoltage (4), Supervision limit hurt: Terminal voltage is too high // outputFailureMaxCurrent (5), Supervision limit hurt: Current is too high // outputFailureMaxTemperature (6), Supervision limit hurt: Heat sink temperature is too high // outputFailureMaxPower (7), Supervision limit hurt: Output power is too high // -- reserved // outputFailureTimeout (9), Communication timeout between output channel and main control // outputCurrentLimited (10), Current limiting is active (constant current mode) // outputRampUp (11), Output voltage is increasing (e.g. after switch on) // outputRampDown (12), Output voltage is decreasing (e.g. after switch off) // outputEnableKill (13), EnableKill is aktive // outputEmergencyOff (14), EmergencyOff event is aktive // outputAdjusting (15), Fine adjustment is working // outputConstantVoltage (16), Voltage control (constant voltage mode) // outputVoltageBoundsExceeded (17), output Voltage out of bounds // outputCurrentBoundsExceeded (18), output Current out of bounds // outputFailureCurrentLimit (19) Hardware current limit (EHS) / trip (EDS, EBS) was exceeded epicsExportAddress(int, MpodStatusParserDebug); epicsRegisterFunction(MpodStatusParserInit); epicsRegisterFunction(MpodStatusParserProcess);