Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r47a7da55aea88cd7a2b06870226122d0cc8be540 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 47a7da55aea88cd7a2b06870226122d0cc8be540) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -112,7 +112,7 @@ DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); U32 msSinceLastVolumeCalc = calcTimeSince( resUseTimer ); - F32 flowRateMlPerMs = getMeasuredDialInFlowRate() / (F32)( MS_PER_SECOND * SEC_PER_MIN ); + F32 flowRateMlPerMs = (F32)getTargetDialInFlowRate() / (F32)( MS_PER_SECOND * SEC_PER_MIN ); // calculate volume used from active reservoir resUseVolumeMl += ( flowRateMlPerMs * msSinceLastVolumeCalc ); // TODO - should this calc be done and kept by Dialysis sub-mode? Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r93a439cf9d1b347e23b84d1156417380ee01efaa -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 93a439cf9d1b347e23b84d1156417380ee01efaa) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -54,13 +54,15 @@ static PRESSURE_STATE_T presOcclState = PRESSURE_INIT_STATE; ///< current state of pressure monitor state machine. static U32 presOcclDataPublicationTimerCounter = 0; ///< used to schedule pressure data publication to CAN bus. -DATA_DECL( U32, PresOcclDataPub, presOcclDataPublishInterval, PRES_OCCL_DATA_PUB_INTERVAL, PRES_OCCL_DATA_PUB_INTERVAL ); ///< interval (in ms) at which to publish pressure/occlusion data to CAN bus. -DATA_DECL( F32, ArterialPressure, arterialPressure, 0, 0 ); ///< measured arterial pressure. -DATA_DECL( F32, VenousPressure, venousPressure, 0.0, 0.0 ); ///< measured venous pressure. -DATA_DECL( F32, BloodPumpOcclusion, bloodPumpOcclusion, 0.0, 0.0 ); ///< measured blood pump occlusion pressure. -DATA_DECL( F32, DialInPumpOcclusion, dialInPumpOcclusion, 0.0, 0.0 ); ///< measured dialysate inlet pump occlusion pressure. -DATA_DECL( F32, DialOutPumpOcclusion, dialOutPumpOcclusion, 0.0, 0.0 ); ///< measured dialysate outlet pump occlusion pressure. +static OVERRIDE_F32_T measuredBloodFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< measured blood flow rate +static OVERRIDE_U32_T presOcclDataPublishInterval = { PRES_OCCL_DATA_PUB_INTERVAL, PRES_OCCL_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish pressure/occlusion data to CAN bus. +static OVERRIDE_F32_T arterialPressure = {0.0, 0.0, 0.0, 0 }; ///< measured arterial pressure. +static OVERRIDE_F32_T venousPressure = {0.0, 0.0, 0.0, 0 }; ///< measured venous pressure. +static OVERRIDE_F32_T bloodPumpOcclusion = {0.0, 0.0, 0.0, 0 }; ///< measured blood pump occlusion pressure. +static OVERRIDE_F32_T dialInPumpOcclusion = {0.0, 0.0, 0.0, 0 }; ///< measured dialysate inlet pump occlusion pressure. +static OVERRIDE_F32_T dialOutPumpOcclusion = {0.0, 0.0, 0.0, 0 }; ///< measured dialysate outlet pump occlusion pressure. + static PRESSURE_SELF_TEST_STATE_T presOcclSelfTestState = PRESSURE_SELF_TEST_STATE_START; ///< current pressure self test state. static U32 bloodPumpSelfTestTimerCount = 0; ///< timer counter for pressure self test. Index: firmware/App/HDCommon.h =================================================================== diff -u -r7fa65a3aae9c4ef70a6e53f3e3bb20f0425bd681 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 7fa65a3aae9c4ef70a6e53f3e3bb20f0425bd681) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -29,7 +29,7 @@ // ********** build switches ********** #define UF_TEST_ENABLED 1 -#define UF_TEST_WITH_DG 1 +//#define UF_TEST_WITH_DG 1 #ifndef _RELEASE_ #ifndef _VECTORCAST_ // #define RM46_EVAL_BOARD_TARGET 1 @@ -45,6 +45,8 @@ #define DISABLE_PRESSURE_CHECKS 1 // #define SHOW_LOAD_CELL_IN_ROTOR_RPM 1 // #define READ_FPGA_ASYNC_DATA 1 +// #define EMC_TEST_BUILD 1 + #define ALARMS_DEBUG 1 #include #include Index: firmware/App/Modes/ModeFault.c =================================================================== diff -u -r2df21d2472a8d79d78af7e359518acf3614accc5 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision 2df21d2472a8d79d78af7e359518acf3614accc5) +++ firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -15,6 +15,12 @@ **************************************************************************/ #include "AlarmLamp.h" +#ifdef EMC_TEST_BUILD // TODO - test code +#include "BloodFlow.h" +#include "Buttons.h" +#include "DialInFlow.h" +#include "DialOutFlow.h" +#endif #include "OperationModes.h" #include "ModeFault.h" @@ -64,6 +70,33 @@ *************************************************************************/ U32 execFaultMode( void ) { +#ifdef EMC_TEST_BUILD // TODO - test code + static BOOL toggle = FALSE; + static BOOL button_state = FALSE; + BOOL stop = isStopButtonPressed(); + + if ( TRUE == stop ) + { + if ( stop != button_state ) + { + toggle = ( toggle == TRUE ? FALSE : TRUE ); + if ( TRUE == toggle ) + { + setBloodPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + else + { + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + } + } + button_state = stop; +#endif + return 0; // TODO - return current state } Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r47a7da55aea88cd7a2b06870226122d0cc8be540 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 47a7da55aea88cd7a2b06870226122d0cc8be540) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -92,7 +92,11 @@ *************************************************************************/ U32 execStandbyMode( void ) { - BOOL stop = isStopButtonPressed(); +#ifdef EMC_TEST_BUILD + static BOOL toggle = FALSE; + static BOOL button_state = FALSE; +#endif +BOOL stop = isStopButtonPressed(); DG_OP_MODE_T dgOpMode = getDGOpMode(); // TODO - the DG mode & sub-mode come as a pair at interval - they MUST be kept together. U32 dgSubMode = getDGSubMode(); @@ -202,8 +206,30 @@ // TODO - test code if ( TRUE == stop ) { +#ifdef EMC_TEST_BUILD + if ( stop != button_state ) + { + toggle = ( toggle == TRUE ? FALSE : TRUE ); + if ( TRUE == toggle ) + { + setBloodPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + else + { + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + } +#else requestNewOperationMode( MODE_TPAR ); +#endif } +#ifdef EMC_TEST_BUILD + button_state = stop; +#endif break; default: Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rf861c4c5ab64f429e0b8b9cc456e2ed14e472f2b -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision f861c4c5ab64f429e0b8b9cc456e2ed14e472f2b) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -701,7 +701,9 @@ /*********************************************************************//** * @brief * The broadcastTreatmentSettingsRanges function computes and broadcasts \n - * updated treatment parameter ranges that the user may change during treatment. + * updated treatment parameter ranges that the user may change during treatment. \n + * It is assumed that prescription settings have already been set prior to calling \n + * this function. * @details * Inputs : current operating mode, treatment states and parameters * Outputs : valid ranges message sent on interval @@ -712,21 +714,24 @@ if ( ++treatmentParamsRangesBroadcastTimerCtr >= TREATMENT_SETTINGS_RANGES_PUB_INTERVAL ) { // compute minimum treatment duration - U32 elapseTime = CALC_ELAPSED_TREAT_TIME_IN_MIN() + 2; // add two minutes to cover rounding and ensure it's valid for next minute - U32 minTime = MAX( elapseTime, MIN_TREATMENT_TIME_MINUTES ); // treatment duration cannot be < 1 hour + U32 presTime = ( presTreatmentTimeSecs / SEC_PER_MIN ); + U32 elapseTime = CALC_ELAPSED_TREAT_TIME_IN_MIN(); + U32 minTime = MAX( (elapseTime + 2), MIN_TREATMENT_TIME_MINUTES ); // treatment duration cannot be < 1 hour. add two minutes to cover rounding and ensure it's valid for next minute // compute maximum treatment duration (from both UF and dialysate volume perspectives) U32 maxTimeRem = ( MAX_UF_VOLUME_ML - (U32)getUltrafiltrationVolumeCollected() ) / ( presUFRate > 0.0 ? (U32)presUFRate : 1 ); U32 maxTime1 = minTime + maxTimeRem; U32 maxTime2 = MAX_DIALYSATE_VOLUME_ML / presDialysateFlowRate; - U32 maxTime = MIN( maxTime1, maxTime2 ); + U32 maxTime = MAX( maxTime1, maxTime2 ); // compute minimum UF volume F32 minUFVol = getUltrafiltrationVolumeCollected() + presUFRate; - // compute maximum UF volume (considering from adjustment of UF rate perspective) - F32 maxUFVol = ( presUFRate > 0.0 ? minUFVol + ( (F32)( MAX_TREATMENT_TIME_MINUTES - CALC_ELAPSED_TREAT_TIME_IN_MIN() - 1 ) * presUFRate ) : (F32)MAX_UF_VOLUME_ML ); + // compute maximum UF volume (considering from adjustment of UF rate and time perspectives) + F32 maxUFVol1 = minUFVol + ( (F32)( presTime - elapseTime ) * MAX_UF_RATE_ML_MIN ); + F32 maxUFVol2 = ( presUFRate > 0.0 ? minUFVol + ( (F32)( MAX_TREATMENT_TIME_MINUTES - elapseTime - 1 ) * presUFRate ) : minUFVol ); + F32 maxUFVol = MAX( maxUFVol1, maxUFVol2 ); // compute minimum dialysate flow rate U32 minDialRate = MIN_DIAL_IN_FLOW_RATE; // compute maximum dialysate flow rate from max dialysate volume perspective - U32 maxDialRate = MAX_DIALYSATE_VOLUME_ML / ( presTreatmentTimeSecs / SEC_PER_MIN ); + U32 maxDialRate = MAX_DIALYSATE_VOLUME_ML / presTime; // now ensure maximums do not exceed the literal maximums maxTime = MIN( maxTime, MAX_TREATMENT_TIME_MINUTES ); Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rc9cf3c88d4db4ddeb62c85489bbcb25e48688c35 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision c9cf3c88d4db4ddeb62c85489bbcb25e48688c35) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -253,14 +253,6 @@ // activate alarm alarmIsActive[ alarm ] = TRUE; alarmStartedAt[ alarm ].data = getMSTimerCount(); -#ifdef DEBUG_ENABLED - { - // TODO - temporary debug code - remove later - char debugStr[ 256 ]; - sprintf( debugStr, "ALARM triggered:%5d \n", alarm ); - sendDebugData( (U08*)debugStr, strlen(debugStr) ); - } -#endif } } else @@ -289,6 +281,16 @@ broadcastAlarmTriggered( (U16)alarm, blankAlarmData, blankAlarmData ); } activateAlarm( alarm ); +#ifdef DEBUG_ENABLED +#ifdef ALARMS_DEBUG + { + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; + sprintf( debugStr, "ALARM triggered:%5d \n", alarm ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + } +#endif +#endif } /************************************************************************* @@ -311,6 +313,16 @@ broadcastAlarmTriggered( (U16)alarm, alarmData, blankAlarmData ); } activateAlarm( alarm ); +#ifdef DEBUG_ENABLED +#ifdef ALARMS_DEBUG + { + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; + sprintf( debugStr, "ALARM triggered:%5d %8X \n", alarm, alarmData.data.uInt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + } +#endif +#endif } /************************************************************************* @@ -334,6 +346,16 @@ broadcastAlarmTriggered( (U16)alarm, alarmData1, alarmData2 ); } activateAlarm( alarm ); +#ifdef DEBUG_ENABLED +#ifdef ALARMS_DEBUG + { + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; + sprintf( debugStr, "ALARM triggered:%5d %8X %8X \n", alarm, alarmData1.data.uInt, alarmData2.data.uInt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + } +#endif +#endif } /************************************************************************* @@ -365,6 +387,16 @@ { resetAlarmPriorityFIFO( alarmTable[ alarm ].alarmPriority ); } +#ifdef DEBUG_ENABLED +#ifdef ALARMS_DEBUG + { + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; + sprintf( debugStr, "ALARM cleared:%5d \n", alarm ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + } +#endif +#endif } } } Index: firmware/App/Services/CommBuffers.c =================================================================== diff -u -r2112e3143003eaf9584d4be068f7ca89b33c941a -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision 2112e3143003eaf9584d4be068f7ca89b33c941a) +++ firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -24,26 +24,31 @@ #include // for memcpy() #include "CommBuffers.h" +#include "SystemCommMessages.h" +#include "Timers.h" // ********** private definitions ********** #define COMM_BUFFER_LENGTH 512 // max bytes in each comm buffer (double if you count double buffers) #define DOUBLE_BUFFERS 2 // need 2 buffers for double buffering +#define BUFFER_OVERFLOW_PERSISTENCE_MS 5000 // how many ms buffer overflows must persist before fault // ********** private data ********** static volatile U32 commBufferByteCount[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ]; // for each buffer, how many bytes does it contain? (also index to next available) static volatile U32 activeDoubleBuffer[ NUM_OF_COMM_BUFFERS ]; // for each buffer, which double buffer is being fed right now? static U08 commBuffers[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ][ COMM_BUFFER_LENGTH ]; // each is double buffered to avoid thread contention static volatile BOOL bufferGetLock[ NUM_OF_COMM_BUFFERS ]; // prevent getter from accessing active buffer while add in progress +static U32 firstBufferOverflowTimeStamp = 0; // time stamp of a prior overflow event - allows for an overflow persistence check // ********** private function prototypes ********** +static void clearBuffer( COMM_BUFFER_T buffer ); static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ); /************************************************************************* - * @brief initCommBuffers + * @brief * The initCommBuffers function initializes the CommBuffers module. * @details * Inputs : none @@ -53,25 +58,46 @@ *************************************************************************/ void initCommBuffers( void ) { - S32 b,d,i; + S32 b; // reset and zero out all buffers for ( b = 0; b < NUM_OF_COMM_BUFFERS; b++ ) { - activeDoubleBuffer[ b ] = 0; + clearBuffer( (COMM_BUFFER_T)b ); + } +} + +/************************************************************************* + * @brief + * The clearBuffer function clears (empties) a given buffer. \n + * Caller should ensure buffer won't be used while this function is clearing \n + * the buffer. + * @details + * Inputs : none + * Outputs : given buffer is cleared. + * @param buffer : the buffer to clear + * @return none + *************************************************************************/ +static void clearBuffer( COMM_BUFFER_T buffer ) +{ + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + S32 d,i; + + activeDoubleBuffer[ buffer ] = 0; for ( d = 0; d < DOUBLE_BUFFERS; d++ ) { - commBufferByteCount[ b ][ d ] = 0; + commBufferByteCount[ buffer ][ d ] = 0; for ( i = 0; i < COMM_BUFFER_LENGTH; i++ ) { - commBuffers[ b ][ d ][ i ] = 0; + commBuffers[ buffer ][ d ][ i ] = 0; } } } } /************************************************************************* - * @brief addToCommBuffer + * @brief * The addToCommBuffer function adds data of specified length to a specified \n * communication buffer. S/W fault if buffer too full to add data. \n * This function will always add to the active double buffer. \n @@ -123,15 +149,43 @@ else // buffer too full to add this much data { bufferFull = TRUE; + clearBuffer( buffer ); } // release thread protection bufferGetLock[ buffer ] = FALSE; _enable_IRQ(); - // if buffer was full, trigger s/w fault + // if buffer was full, check persistence - trigger s/w fault if persists if ( TRUE == bufferFull ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, len ) + // not first overflow? + if ( firstBufferOverflowTimeStamp != 0 ) + { + // if buffer overflows persists, fault + if ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, len ) + } + } + else // first overflow - set time stamp for persistence check + { + firstBufferOverflowTimeStamp = getMSTimerCount(); + } +#ifdef DEBUG_ENABLED + { + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; + sprintf( debugStr, "Comm Buffer Overflow:%5d \n", (U32)buffer ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + } +#endif } + else + { // if good for persistence time period, reset persistence check + if ( ( firstBufferOverflowTimeStamp != 0 ) && ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) ) + { + firstBufferOverflowTimeStamp = 0; + } + } } else // invalid buffer given { @@ -142,7 +196,7 @@ } /************************************************************************* - * @brief getFromCommBuffer + * @brief * The getFromCommBuffer function fills a given byte array with a given \n * number of bytes from a given buffer and returns the number of bytes \n * retrieved from the buffer. This function will draw from the inactive \n @@ -203,7 +257,7 @@ } /************************************************************************* - * @brief peekFromCommBuffer + * @brief * The peekFromCommBuffer function fills a given byte array with a given \n * number of bytes from a given buffer. This function does NOT consume \n * the bytes - it only peeks at them. A call to numberOfBytesInCommBuffer() \n @@ -261,7 +315,7 @@ } /************************************************************************* - * @brief numberOfBytesInCommBuffer + * @brief * The numberOfBytesInCommBuffer function determines how many bytes \n * are currently contained in a given comm buffer. Both double buffers \n * are considered for this. @@ -299,7 +353,7 @@ } /************************************************************************* - * @brief switchDoubleBuffer + * @brief * The switchDoubleBuffer function switches the active and inactive buffers \n * for the given buffer. \n * This function should only be called when the current inactive buffer has \n @@ -325,7 +379,7 @@ } /************************************************************************* - * @brief getDataFromInactiveBuffer + * @brief * The getDataFromInactiveBuffer function retrieves a given number of bytes \n * from the inactive buffer of a given buffer. This function should only be \n * called by getFromCommBuffer(). Params will be pre-validated there. Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r7fa65a3aae9c4ef70a6e53f3e3bb20f0425bd681 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 7fa65a3aae9c4ef70a6e53f3e3bb20f0425bd681) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -123,6 +123,10 @@ static U32 badCRCListIdx = 0; // where next bad message CRC time stamp will go in list static U32 badCRCListCount = 0; // # of bad CRCs in the list +#ifdef EMC_TEST_BUILD +static U32 badCANCount; // test code in support of EMC testing +#endif + // ********** private function prototypes ********** #ifdef DEBUG_ENABLED @@ -726,6 +730,10 @@ else if ( -1 == msgSize ) // candidate message with bad CRC found? { badCRCDetected = TRUE; +#ifdef EMC_TEST_BUILD + badCANCount++; + broadcastCANErrorCount( badCANCount ); +#endif getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, 1 ); // consume sync byte so we can re-sync messagesInBuffer = TRUE; // keep processing this buffer } // looks like there is a complete message in the comm buffer @@ -864,6 +872,10 @@ } else // CRC failed { +#ifdef EMC_TEST_BUILD + badCANCount++; + broadcastCANErrorCount( badCANCount ); +#endif checkTooManyBadMsgCRCs(); } } Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r47a7da55aea88cd7a2b06870226122d0cc8be540 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 47a7da55aea88cd7a2b06870226122d0cc8be540) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -26,10 +26,11 @@ #include "Dialysis.h" #include "ModeTreatment.h" #include "PresOccl.h" -#include "WatchdogMgmt.h" +#include "SafetyShutdown.h" +#include "SystemComm.h" #include "SystemCommMessages.h" #include "Utilities.h" -#include "SystemComm.h" +#include "WatchdogMgmt.h" #include "RTC.h" // ********** private definitions ********** @@ -1159,6 +1160,27 @@ return result; } +#ifdef EMC_TEST_BUILD +BOOL broadcastCANErrorCount( U32 count ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_CAN_ERROR_COUNT; + msg.hdr.payloadLen = sizeof( U32 ); + + memcpy( payloadPtr, &count, sizeof( U32 ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} +#endif + // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r47a7da55aea88cd7a2b06870226122d0cc8be540 -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 47a7da55aea88cd7a2b06870226122d0cc8be540) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -147,6 +147,11 @@ // MSG_ID_HD_OP_MODE BOOL broadcastHDOperationMode( U32 mode, U32 subMode ); +#ifdef EMC_TEST_BUILD +// MSG_ID_CAN_ERROR_COUNT +BOOL broadcastCANErrorCount( U32 count ); +#endif + // *********** public test support message functions ********** #ifdef DEBUG_ENABLED