Index: firmware/App/Drivers/NVDriver.c =================================================================== diff -u -r43e60a63eae841e599ff9106f43177a8f63d22be -r1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8 --- firmware/App/Drivers/NVDriver.c (.../NVDriver.c) (revision 43e60a63eae841e599ff9106f43177a8f63d22be) +++ firmware/App/Drivers/NVDriver.c (.../NVDriver.c) (revision 1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8) @@ -29,17 +29,6 @@ #define BANK7_SECTOR_0_31_ENABLE_BIT_MASK 0x0000000F ///< Bank7 sector 0 t0 31 enable mask. #define BANK7_SECTOR_32_63_ENABLE_BIT_MASK 0x00000000 ///< Bank7 sector 32 to 63 enable mask. -#define BANK7_SECTOR0_END_ADDRESS 0xF0203FFF ///< Bank7 sector 0 end address. - -#define BANK7_SECTOR1_START_ADDRESS 0xF0204000 ///< Bank7 sector 1 start address. -#define BANK7_SECTOR1_END_ADDRESS 0xF0207FFF ///< Bank7 sector 1 end address. - -#define BANK7_SECTOR2_START_ADDRESS 0xF0208000 ///< Bank7 sector 2 start address. -#define BANK7_SECTOR2_END_ADDRESS 0xF020BFFF ///< Bank7 sector 2 end address. - -#define BANK7_SECTOR3_START_ADDRESS 0xF020C000 ///< Bank7 sector 3 start address. -#define BANK7_SECTOR3_END_ADDRESS 0xF020FFFF ///< Bank7 sector 3 end address. - void initNVDriver( void ) { // Initialize and activate flash bank 7 Index: firmware/App/Drivers/NVDriver.h =================================================================== diff -u -r724f9a0cf2b603e988a519420bf95f4aa4da4b93 -r1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8 --- firmware/App/Drivers/NVDriver.h (.../NVDriver.h) (revision 724f9a0cf2b603e988a519420bf95f4aa4da4b93) +++ firmware/App/Drivers/NVDriver.h (.../NVDriver.h) (revision 1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8) @@ -28,7 +28,17 @@ // ********** public definitions ********** #define BANK7_SECTOR0_START_ADDRESS 0xF0200000 ///< Bank7 sector 0 start address. +#define BANK7_SECTOR0_END_ADDRESS 0xF0203FFF ///< Bank7 sector 0 end address. +#define BANK7_SECTOR1_START_ADDRESS 0xF0204000 ///< Bank7 sector 1 start address. +#define BANK7_SECTOR1_END_ADDRESS 0xF0207FFF ///< Bank7 sector 1 end address. + +#define BANK7_SECTOR2_START_ADDRESS 0xF0208000 ///< Bank7 sector 2 start address. +#define BANK7_SECTOR2_END_ADDRESS 0xF020BFFF ///< Bank7 sector 2 end address. + +#define BANK7_SECTOR3_START_ADDRESS 0xF020C000 ///< Bank7 sector 3 start address. +#define BANK7_SECTOR3_END_ADDRESS 0xF020FFFF ///< Bank7 sector 3 end address. + /// NVDataMgmt memory operation modes enumeration. typedef enum NVDataMgmt_Operation { @@ -45,6 +55,7 @@ NVDATAMGMT_CALIBRATION_RECORD = 0, ///< NVDataMgmt process write calibration record. NVDATAMGMT_SYSTEM_RECORD, ///< NVDataMgmt process write system record. NVDATAMGMT_SERVICE_RECORD, ///< NVDataMgmt process service record. + NVDATAMGMT_INTITUTIONAL_RECORD, ///< NVDataMgmt process institutional record. NVDATAMGMT_USAGE_INFO_RECORD, ///< NVDataMgmt process usage info record. #ifndef _RELEASE_ NVDATAMGMT_SW_CONFIG_RECORD, ///< NVDataMgmt process software record. Index: firmware/App/Services/NVMsgQ.c =================================================================== diff -u -r724f9a0cf2b603e988a519420bf95f4aa4da4b93 -r1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8 --- firmware/App/Services/NVMsgQ.c (.../NVMsgQ.c) (revision 724f9a0cf2b603e988a519420bf95f4aa4da4b93) +++ firmware/App/Services/NVMsgQ.c (.../NVMsgQ.c) (revision 1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8) @@ -18,6 +18,7 @@ #include "MsgDefs.h" #include "NVMsgQ.h" #include "NVRecordsDD.h" +#include "OperationModes.h" #include "TaskGeneral.h" #include "Timers.h" #include "Utilities.h" // For crc calculation @@ -74,6 +75,13 @@ U08 data[NUM_OF_BYTES_PER_RECORD_PAYLOAD]; } DD_NVM_RECORD_PAYLOAD_T; +/// DD institutional values structure. +typedef struct +{ + U32 minRORejectionRatioPCT; ///< Min RO rejection ratio in percent. + F32 minInletWaterCondAlarmLimitUSPCM; ///< Min inlet water conductivity alarm limit in uS/cm. +} DD_INSTITUTIONAL_VALUES_T; + // ********** private data ********** static PROCESS_RECORD_JOB_T recordJobQueue[ QUEUE_MAX_SIZE ]; ///< Record queue jobs. @@ -103,6 +111,8 @@ // Process record functions static PROCESS_RECORD_STATE_T handleExecProcessRecordIdleState( void ); static PROCESS_RECORD_STATE_T handleExecProcessRecordSendRecordState( void ); +static void sendInstitutionalRecordToUI( DD_INSTITUTIONAL_LOCAL_RECORD_T* instit ); +static void handleDGRequestInstitutionalValues( MESSAGE_T* message ); static BOOL sendDDRecord( MSG_ID_T msgId, U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ); static RECORD_JOBS_STATE_T getNVMRecordJobState( MSG_ID_T msgID ); static MSG_ID_T getNVMRecordResponseMsgId (RECORD_JOBS_STATE_T job ); @@ -125,9 +135,6 @@ hasPublishRecordBeenRequested[ NVDATAMGMT_SYSTEM_RECORD ] = FALSE; hasPublishRecordBeenRequested[ NVDATAMGMT_SERVICE_RECORD ] = FALSE; hasPublishRecordBeenRequested[ NVDATAMGMT_USAGE_INFO_RECORD ] = FALSE; -#ifndef _RELEASE_ - hasPublishRecordBeenRequested[ NVDATAMGMT_SW_CONFIG_RECORD ] = FALSE; -#endif newCalStartTimer = 0; @@ -518,6 +525,92 @@ /*********************************************************************//** * @brief + * The handleSendInstitutionalRecordToUI function sends the institutional record to UI + * @details Inputs: none + * @details Outputs: none + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSendInstitutionalRecordToUI( MESSAGE_T* message ) +{ + if ( 0 == message->hdr.payloadLen ) + { + DD_INSTITUTIONAL_RECORD_T ddInstitutionalRecord; + DD_INSTITUTIONAL_LOCAL_RECORD_T ddInstitutionalLocalRecord; + + getNVRecord2Driver( GET_INSTITUTIONAL_RECORD, (U08*)&ddInstitutionalRecord, sizeof( DD_INSTITUTIONAL_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + + memcpy( &ddInstitutionalLocalRecord, &ddInstitutionalRecord, sizeof( DD_INSTITUTIONAL_LOCAL_RECORD_T ) ); + + sendInstitutionalRecordToUI( &ddInstitutionalLocalRecord ); + } +} + +/*********************************************************************//** + * @brief + * The sendInstitutionalRecordToUI function sends the institutional record to UI + * @details Inputs: none + * @details Outputs: none + * @param instit a pointer to the local institutional recored in the system + * messages that is without calibration time and crc + * @return none + *************************************************************************/ +static void sendInstitutionalRecordToUI( DD_INSTITUTIONAL_LOCAL_RECORD_T* instit ) +{ + MESSAGE_T msg; + + U08 *payloadPtr = msg.payload; + U32 accept = 1; + U32 reason = 0; + + // Create a message record + blankMessage( &msg ); +// msg.hdr.msgID = MSG_ID_HD_INSTITUTIONAL_RECORD_RESPONSE; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( DD_INSTITUTIONAL_LOCAL_RECORD_T ); + + memcpy( payloadPtr, &accept, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &reason, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, instit, sizeof( DD_INSTITUTIONAL_LOCAL_RECORD_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer +// serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); +} + +/*********************************************************************//** + * @brief + * The handleDGRequestInstitutionalValues function handles the DG request + * to receive the DG institutional values from HD institutional record. + * @details Inputs: none + * @details Outputs: none + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +static void handleDGRequestInstitutionalValues( MESSAGE_T* message ) +{ + if ( 0 == message->hdr.payloadLen ) + { + MESSAGE_T msg; + DD_INSTITUTIONAL_VALUES_T ddInstitValues; + + ddInstitValues.minRORejectionRatioPCT = getMinRORejectionRatioInInstitRecordPCT(); + ddInstitValues.minInletWaterCondAlarmLimitUSPCM = getMinInletWaterConductivityLimitInstitRecordUSPCM(); + + // Create a message record + blankMessage( &msg ); +// msg.hdr.msgID = MSG_ID_DG_INSTIT_VALUES_FROM_HD_INSTIT_RECORD_RESPONSE; + msg.hdr.payloadLen = sizeof( DD_INSTITUTIONAL_VALUES_T ); + + memcpy( msg.payload, &ddInstitValues, sizeof( DD_INSTITUTIONAL_VALUES_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer +// serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_DG, ACK_REQUIRED ); + } +} + +/*********************************************************************//** + * @brief * The receiveRecordFromDialin function receives the record that has been sent * from Dialin and if the CRCs passed, it schedules a write to the NV data. * @details Inputs: currentMessage, nvDataMgmtExecReceiveRecordState, @@ -569,6 +662,12 @@ // Get the CRC of the structure without the last 16 bits which is the CRC as well as the padding values U16 recordCRC = *(U16*)recordSpec.structCRCPtr; + if ( NVDATAMGMT_INTITUTIONAL_RECORD == job ) + { +// isInstRcrdValid = isNVInstitutionalRecordInRange( &ddInstitutionalGroup.ddInstitutionalRecord ); + status = isInstRcrdValid; + } + if ( ( calcCRC != recordCRC ) || ( FALSE == isInstRcrdValid ) ) { // Institutional record has failed so do not write it into the NV memory and read back what was in the NV memory @@ -583,6 +682,18 @@ // CRC passed, enqueue an erase, a write of calibration data and a write of service record BOOL scheduleStatus = enqueueSector0Records(); + MESSAGE_T institMsg; + // Got new data for the EEPROM records, set the latest institutional record to treatment parameters to make sure + // the treatment parameters have the record available all the time +// setNVInstitutionalRecordToTxParamsRecord( &ddInstitutionalGroup.ddInstitutionalRecord ); + + // Received new institutional record and it is valid, send it to the UI to be up to date + institMsg.hdr.msgID = 0; + institMsg.hdr.payloadLen = 0; + handleSendInstitutionalRecordToUI( &institMsg ); + // Received new institutional record and it is valid, send it to the DG to be up to date + handleDGRequestInstitutionalValues( &institMsg ); + // Signal that there is a new calibration record available. // NOTE: as of now, this signal will be sent even after the system record is sent newCalStartTimer = getMSTimerCount(); @@ -660,12 +771,6 @@ job = NVDATAMGMT_USAGE_INFO_RECORD; break; -#ifndef _RELEASE_ - case MSG_ID_DD_NVM_SET_SW_CONFIG_RECORD: - job = NVDATAMGMT_SW_CONFIG_RECORD; - break; -#endif - default: // Software Fault break; @@ -697,12 +802,6 @@ msgID = MSG_ID_DD_NVM_SEND_USAGE_INFO_RECORD; break; -#ifndef _RELEASE_ - case NVDATAMGMT_SW_CONFIG_RECORD: - msgID = MSG_ID_DD_NVM_SEND_SW_CONFIG_RECORD; - break; -#endif - default: // Software fault break; Index: firmware/App/Services/NVMsgQ.h =================================================================== diff -u -r724f9a0cf2b603e988a519420bf95f4aa4da4b93 -r1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8 --- firmware/App/Services/NVMsgQ.h (.../NVMsgQ.h) (revision 724f9a0cf2b603e988a519420bf95f4aa4da4b93) +++ firmware/App/Services/NVMsgQ.h (.../NVMsgQ.h) (revision 1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8) @@ -29,17 +29,19 @@ // ********** public definitions ********** -#define NV_MEM_BASE_ADDRESS BANK7_SECTOR0_START_ADDRESS -#define NV_RECORD_SLOT_SIZE 4096 // 4K +#define NV_RECORD_SLOT_SIZE 4096 // 4K -#define SYSTEM_RECORD_OFFSET (0U * NV_RECORD_SLOT_SIZE) -#define SERVICE_RECORD_OFFSET (1U * NV_RECORD_SLOT_SIZE) -#define CAL_RECORD_OFFSET (2U * NV_RECORD_SLOT_SIZE) +#define SYSTEM_RECORD_OFFSET (0U * NV_RECORD_SLOT_SIZE) +#define SERVICE_RECORD_OFFSET (0U * NV_RECORD_SLOT_SIZE) +#define CAL_RECORD_OFFSET (1U * NV_RECORD_SLOT_SIZE) +#define INSTIT_RECORD_OFFSET (0U * NV_RECORD_SLOT_SIZE) +#define USAGE_RECORD_OFFSET (0U * NV_RECORD_SLOT_SIZE) -#define SYSTEM_RECORD_NV_MEM_START_ADDRESS (NV_MEM_BASE_ADDRESS + SYSTEM_RECORD_OFFSET) -#define SERVICE_RECORD_NV_MEM_START_ADDRESS (NV_MEM_BASE_ADDRESS + SERVICE_RECORD_OFFSET) -#define CAL_RECORD_NV_MEM_START_ADDRESS (NV_MEM_BASE_ADDRESS + CAL_RECORD_OFFSET) -#define DD_USAGE_INFO_START_ADDRESS 0x00000030 /* 48 */ ///< DG usage info start address in RTC RAM (48). +#define SYSTEM_RECORD_NV_MEM_START_ADDRESS ( BANK7_SECTOR0_START_ADDRESS + SYSTEM_RECORD_OFFSET ) +#define SERVICE_RECORD_NV_MEM_START_ADDRESS ( BANK7_SECTOR1_START_ADDRESS + SERVICE_RECORD_OFFSET ) +#define CAL_RECORD_NV_MEM_START_ADDRESS ( BANK7_SECTOR1_START_ADDRESS + CAL_RECORD_OFFSET ) +#define INSTIT_RECORD_NV_MEM_START_ADDRESS ( BANK7_SECTOR2_START_ADDRESS + INSTIT_RECORD_OFFSET ) +#define USAGE_INFO_START_ADDRESS ( BANK7_SECTOR3_START_ADDRESS + USAGE_RECORD_OFFSET ) ///< DD usage info start address in RTC RAM (48). #define MIN_JOBS_NEEDED_FOR_SECTOR_0 5U ///< Min queue count needed to erase and write all (5) records back in sector 0. @@ -69,6 +71,7 @@ BOOL testDDGetNVRecord( MESSAGE_T *message ); BOOL testDDSetNVRecord( MESSAGE_T *message ); +void handleSendInstitutionalRecordToUI( MESSAGE_T* message ); BOOL receiveRecordFromDialin( RECORD_JOBS_STATE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); BOOL isNewCalibrationRecordAvailable( void ); Index: firmware/App/Services/NVRecordsDD.c =================================================================== diff -u -r724f9a0cf2b603e988a519420bf95f4aa4da4b93 -r1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8 --- firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision 724f9a0cf2b603e988a519420bf95f4aa4da4b93) +++ firmware/App/Services/NVRecordsDD.c (.../NVRecordsDD.c) (revision 1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8) @@ -66,6 +66,9 @@ #define DEFAULT_BIC_TEST_ACID_SNSR_US_PER_CM 0.0F ///< Bicarb test acid sensor conductivity uS/cm. #define DEFAULT_BIC_TEST_BIC_SNSR_US_PER_CM 3890.0F ///< Bicarb test bicarb sensor conductivity uS/cm. +#define DEFAULT_MAX_RO_REJECTION_RATIO_PCT 90 ///< Max RO rejection ratio in percent. +#define DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM 200.0F ///< Min inlet water conductivity alarm limit in uS/cm. + #define MAX_NUM_OF_WRITE_TRIES 3U ///< Max number of write tries. #define RECORD_BYTE_SIZE(r) (sizeof(r) + sizeof(U16)) ///< Record byte size macro. @@ -85,53 +88,62 @@ /// DD calibration groups structure typedef struct { - DD_PRES_SENSORS_CAL_RECORD_T presSensorsCalRecord; ///< DG pressure sensors. - DD_FLOW_SENSORS_CAL_RECORD_T flowSensorsCalRecord; ///< DG flow sensors. - DD_TEMP_SENSORS_CAL_RECORD_T tempSensorsCalRecord; ///< DG temperature sensors. - DD_CONC_PUMPS_CAL_RECORD_T concentratePumpsRecord; ///< DG concentrate pumps. - DD_DRAIN_PUMP_CAL_RECORD_T drainPumpRecord; ///< DG drain pump. - DD_RO_PUMP_CAL_RECORD_T roPumpRecord; ///< DG RO pump. - DD_DRAIN_LINE_VOLUME_T drainLineVolumeRecord; ///< DG drain line volume. - DD_PRE_RO_PURGE_VOLUME_T preROPurgeVolumeRecord; ///< DG RO purge volume. - DD_GENERIC_VOLUME_RECORD_T genericVolumeRecord; ///< DG generic volume (magic number because the value is unknown). - DD_ACID_CONCENTRATES_RECORD_T acidConcentratesRecord; ///< DG acid concentrates. - DD_BICARB_CONCENTRATES_RECORD_T bicarbConcentratesRecord; ///< DG bicarb concentrates. - DD_FILTERS_CAL_RECORD_T filtersRecord; ///< DG filters. - DD_FANS_CAL_RECORD_T fansRecord; ///< DG fans. - DD_ACCEL_SENSOR_CAL_RECORD_T accelerometerSensorCalRecord; ///< DG accelerometer sensor. - DD_HEATING_CAL_RECORD_T heatingCalRecord; ///< DG heating calibration record. - DD_CHEMICALS_FILL_COND_CAL_RECORD_T fillCondCalRecord; ///< DG fill acid/bicarb target conductivities calibration record. + DD_PRES_SENSORS_CAL_RECORD_T presSensorsCalRecord; ///< DD pressure sensors. + DD_FLOW_SENSORS_CAL_RECORD_T flowSensorsCalRecord; ///< DD flow sensors. + DD_TEMP_SENSORS_CAL_RECORD_T tempSensorsCalRecord; ///< DD temperature sensors. + DD_CONC_PUMPS_CAL_RECORD_T concentratePumpsRecord; ///< DD concentrate pumps. + DD_DRAIN_PUMP_CAL_RECORD_T drainPumpRecord; ///< DD drain pump. + DD_RO_PUMP_CAL_RECORD_T roPumpRecord; ///< DD RO pump. + DD_DRAIN_LINE_VOLUME_T drainLineVolumeRecord; ///< DD drain line volume. + DD_PRE_RO_PURGE_VOLUME_T preROPurgeVolumeRecord; ///< DD RO purge volume. + DD_GENERIC_VOLUME_RECORD_T genericVolumeRecord; ///< DD generic volume (magic number because the value is unknown). + DD_ACID_CONCENTRATES_RECORD_T acidConcentratesRecord; ///< DD acid concentrates. + DD_BICARB_CONCENTRATES_RECORD_T bicarbConcentratesRecord; ///< DD bicarb concentrates. + DD_FILTERS_CAL_RECORD_T filtersRecord; ///< DD filters. + DD_FANS_CAL_RECORD_T fansRecord; ///< DD fans. + DD_ACCEL_SENSOR_CAL_RECORD_T accelerometerSensorCalRecord; ///< DD accelerometer sensor. + DD_HEATING_CAL_RECORD_T heatingCalRecord; ///< DD heating calibration record. + DD_CONCENTRATES_COND_CAL_RECORD_T concentratesCondCalRecord; ///< DD fill acid/bicarb target conductivities calibration record. } DD_CALIBRATION_GROUPS_T; /// DG calibration records structure typedef struct { - DD_CALIBRATION_GROUPS_T ddCalibrationGroups; ///< DG calibration groups. - U08 padding[ RECORD_PADDING_LENGTH(DD_CALIBRATION_GROUPS_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG calibration record padding byte array. + DD_CALIBRATION_GROUPS_T ddCalibrationGroups; ///< DD calibration groups. + U08 padding[ RECORD_PADDING_LENGTH(DD_CALIBRATION_GROUPS_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD calibration record padding byte array. U16 crc; ///< CRC for the DG calibration record structure. } DD_CALIBRATION_RECORD_T; /// DG system group structure typedef struct { - DD_SYSTEM_RECORD_T ddSystemRecord; ///< DG system record. - U08 padding[ RECORD_PADDING_LENGTH(DD_SYSTEM_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG system group padding byte array. + DD_SYSTEM_RECORD_T ddSystemRecord; ///< DD system record. + U08 padding[ RECORD_PADDING_LENGTH(DD_SYSTEM_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD system group padding byte array. U16 crc; ///< CRC for the DG system group structure. } DD_SYSTEM_GROUP_T; /// DG service record structure typedef struct { - DD_SERVICE_RECORD_T ddServiceRecord; ///< DG service record. - U08 padding[ RECORD_PADDING_LENGTH(DD_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG service group padding. + DD_SERVICE_RECORD_T ddServiceRecord; ///< DD service record. + U08 padding[ RECORD_PADDING_LENGTH(DD_SERVICE_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD service group padding. U16 crc; ///< CRC for the DG service structure. } DD_SERVICE_GROUP_T; + +/// DD institutional record structure +typedef struct +{ + DD_INSTITUTIONAL_RECORD_T ddInstitutionalRecord; ///< DD institutional record. + U08 padding[ RECORD_PADDING_LENGTH(DD_INSTITUTIONAL_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD institutional group padding. + U16 crc; ///< CRC for the HD institutional structure. +} DD_INSTITUTIONAL_GROUP_T; + /// DG usage record structure typedef struct { - DD_USAGE_INFO_RECORD_T ddUsageInfo; ///< DG usage info record. - U08 padding[ RECORD_PADDING_LENGTH(DD_USAGE_INFO_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DG scheduled run group padding. + DD_USAGE_INFO_RECORD_T ddUsageInfo; ///< DD usage info record. + U08 padding[ RECORD_PADDING_LENGTH(DD_USAGE_INFO_RECORD_T, MAX_EEPROM_WRITE_BUFFER_BYTES) ]; ///< DD scheduled run group padding. U16 crc; ///< CRC for the DG usage info structure. } DD_USAGE_INFO_GROUP_T; @@ -140,18 +152,20 @@ // ********** private data ********** // Calibration variables -static DD_CALIBRATION_RECORD_T ddCalibrationRecord; ///< DG calibration record structure (including padding and final CRC). -static DD_SYSTEM_GROUP_T ddSystemGroup; ///< DG system group structure (including padding and final CRC). -static DD_SERVICE_GROUP_T ddServiceGroup; ///< DG service group structure (including padding and final CRC). -static DD_USAGE_INFO_GROUP_T ddUsageInfoGroup; ///< DG usage info structure (including padding and final CRC). +static DD_CALIBRATION_RECORD_T ddCalibrationRecord; ///< DD calibration record structure (including padding and final CRC). +static DD_SYSTEM_GROUP_T ddSystemGroup; ///< DD system group structure (including padding and final CRC). +static DD_SERVICE_GROUP_T ddServiceGroup; ///< DD service group structure (including padding and final CRC). +static DD_INSTITUTIONAL_GROUP_T ddInstitutionalGroup; ///< DD institutional group structure (including padding and final CRC). +static DD_USAGE_INFO_GROUP_T ddUsageInfoGroup; ///< DD usage info structure (including padding and final CRC). // Process records specifications const PROCESS_RECORD_SPECS_T RECORDS_SPECS[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { // Start address Size of the job Max write bytes per job Max read bytes per job Record structure pointer Record CRC pointer Event calibration record update {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddCalibrationRecord, (U08*)&ddCalibrationRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SYSTEM_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddSystemGroup, (U08*)&ddSystemGroup.crc, DD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddServiceGroup, (U08*)&ddServiceGroup.crc, DD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD - {DD_USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddUsageInfoGroup, (U08*)&ddUsageInfoGroup.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO_RECORD + {INSTIT_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_INSTITUTIONAL_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_INSTITUTIONAL_GROUP_T), (U08*)&ddInstitutionalGroup, (U08*)&ddInstitutionalGroup.crc, DD_EVENT_INSTIT_RECORD_UPDATE }, // NVDATAMGMT_INTITUTIONAL_RECORD + {USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), MAX_EEPROM_WRITE_BUFFER_BYTES, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddUsageInfoGroup, (U08*)&ddUsageInfoGroup.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO_RECORD }; static NVDATAMGMT_SELF_TEST_STATE_T nvDataMgmtSelfTestState; ///< NVDataMgmt self-test state variable. @@ -434,6 +448,62 @@ /*********************************************************************//** * @brief + * The isddInstitutionalRecordValid function checks the validity of the HD + * institutional record. + * @details Inputs: ddInstitutionalGroup.ddInstitutionalRecord + * @details Outputs: none + * @return TRUE if the HD institutional record is valid otherwise FALSE + *************************************************************************/ +static BOOL isddInstitutionalRecordValid( void ) +{ + BOOL status = TRUE; + U16 calcCRC = crc16( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); + U16 recordCRC = ddInstitutionalGroup.ddInstitutionalRecord.crc; + + if ( calcCRC != recordCRC ) + { + // CRC did not pass so set all values to default +// ddInstitutionalGroup.ddInstitutionalRecord.minBloodFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_BLOOD_FLOW, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxBloodFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_BLOOD_FLOW, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minDialysateFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_FLOW, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateFlowMLPM = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_FLOW, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minTxDurationMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_TREATMENT_DURATION, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxTxDurationMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_TREATMENT_DURATION, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minStopHeparinDispBeforeTxEndMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxStopHeparinDispBeforeTxEndMIN = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minSalineBolusVolumeML = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxSalineBolusVolumeML = getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minDialysateTempC = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_TEMPERATURE, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxDialysateTempC = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_DIALYSATE_TEMPERATURE, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minArtPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxArtPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minVenPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxVenPressLimitWindowMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minVenAsymPressLimitMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxVenAsymPressLimitMMHG = getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minUFVolumeL = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_UF_VOLUME, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxUFVolumeL = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_UF_VOLUME, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minHeparinDispRateMLPHR = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxHeparinDispRateMLPHR = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minHeparinBolusVolumeML = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, TRUE ); +// ddInstitutionalGroup.ddInstitutionalRecord.maxHeparinBolusVolumeML = getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, FALSE ); +// ddInstitutionalGroup.ddInstitutionalRecord.minRORejectionRatioPCT = DEFAULT_MAX_RO_REJECTION_RATIO_PCT; +// ddInstitutionalGroup.ddInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM = DEFAULT_MIN_INLET_WATER_COND_ALARM_US_P_CM; +// ddInstitutionalGroup.ddInstitutionalRecord.calibrationTime = getRTCTimestamp(); +// ddInstitutionalGroup.ddInstitutionalRecord.crc = crc16 ( (U08*)&ddInstitutionalGroup.ddInstitutionalRecord, +// sizeof( DD_INSTITUTIONAL_RECORD_T ) - sizeof( U16 ) ); +// ddInstitutionalGroup.crc = crc16 ( (U08*)&ddInstitutionalGroup, sizeof( HD_INSTITUTIONAL_GROUP_T ) - sizeof( U16 ) ); + status = FALSE; + + // Institutional record failure is also considered as RTC RAM failure +// activateAlarmNoData( ALARM_ID_HD_INVALID_INSTITUTIONAL_RECORD_CRC ); + } + + return status; +} + +/*********************************************************************//** + * @brief * The isDDUsageRecordValid function checks whether the DG usage information * is valid or not. * @details Inputs: ddUsageInfoGroup @@ -599,7 +669,7 @@ isCalRecordValid = isCalRecordValid == FALSE ? FALSE : isHardwareRecordValid; DD_FILL_COND_OPS_T j; - DD_CHEMICALS_FILL_COND_CAL_RECORD_T* acidBicarbTempRecord = &ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord; + DD_CONCENTRATES_COND_CAL_RECORD_T* acidBicarbTempRecord = &ddCalibrationRecord.ddCalibrationGroups.concentratesCondCalRecord; for ( i = 0; i < NUM_OF_ACID_TYPE; i++ ) { for ( j = FILL_COND_NORMAL_OP; j < NUM_OF_FILL_COND_TEST; j++ ) @@ -1150,6 +1220,32 @@ /*********************************************************************//** * @brief + * The getMinRORejectionRatioInInstitRecordPCT returns the value of the min RO + * rejection ratio in institutional record in percent + * @details Inputs: ddInstitutionalGroup + * Output: none + * @return the min RO rejection ratio in institutional record in percent + *************************************************************************/ +U32 getMinRORejectionRatioInInstitRecordPCT( void ) +{ + return ddInstitutionalGroup.ddInstitutionalRecord.minRORejectionRatioPCT; +} + +/*********************************************************************//** + * @brief + * The getMinInletWaterConductivityLimitInstitRecord returns the value of + * the inlet water conductivity alarm limit in uS/cm in institutional record + * @details Inputs: ddInstitutionalGroup + * Output: none + * @return the inlet water conductivity alarm limit in uS/cm in institutional record + *************************************************************************/ +F32 getMinInletWaterConductivityLimitInstitRecordUSPCM( void ) +{ + return ddInstitutionalGroup.ddInstitutionalRecord.minInletWaterCondAlarmLimitUSPCM; +} + +/*********************************************************************//** + * @brief * The getNVRecord2Driver function copies the requested non-volatile * data into the provided buffer by the caller. The function then checks if * the non-volatile data is valid. If the data is not valid, it raises the @@ -1271,14 +1367,14 @@ { DD_FILL_COND_OPS_T fillOps; - nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues; - nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues ); + nvDataStartPtr = (U08*)&ddCalibrationRecord.ddCalibrationGroups.concentratesCondCalRecord.fillCondValues; + nvDataLength = sizeof( ddCalibrationRecord.ddCalibrationGroups.concentratesCondCalRecord.fillCondValues ); for ( i = 0; i < numOfSnsrs2Check; i++ ) { for ( fillOps = FILL_COND_NORMAL_OP; fillOps < NUM_OF_FILL_COND_TEST; fillOps++ ) { - isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.fillCondCalRecord.fillCondValues[ i ][ fillOps ].calibrationTime ? TRUE : FALSE ); + isNVDataInvalid |= ( 0 == ddCalibrationRecord.ddCalibrationGroups.concentratesCondCalRecord.fillCondValues[ i ][ fillOps ].calibrationTime ? TRUE : FALSE ); } } } @@ -1294,6 +1390,11 @@ nvDataLength = sizeof( ddServiceGroup.ddServiceRecord ); break; + case GET_INSTITUTIONAL_RECORD: + nvDataStartPtr = (U08*)&ddInstitutionalGroup.ddInstitutionalRecord; + nvDataLength = sizeof( ddInstitutionalGroup.ddInstitutionalRecord ); + break; + case GET_USAGE_RECORD: nvDataStartPtr = (U08*)&ddUsageInfoGroup.ddUsageInfo; nvDataLength = sizeof( ddUsageInfoGroup.ddUsageInfo ); @@ -1361,6 +1462,11 @@ status = enqueueSector0Records(); break; + case NVDATAMGMT_INTITUTIONAL_RECORD: + ddInstitutionalGroup.ddInstitutionalRecord.crc = crc; + status = enqueueSector0Records(); + break; + case NVDATAMGMT_USAGE_INFO_RECORD: ddUsageInfoGroup.ddUsageInfo.crc = crc; if ( getAvailableRecordQueueCount() > 0 ) Index: firmware/App/Services/NVRecordsDD.h =================================================================== diff -u -r724f9a0cf2b603e988a519420bf95f4aa4da4b93 -r1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8 --- firmware/App/Services/NVRecordsDD.h (.../NVRecordsDD.h) (revision 724f9a0cf2b603e988a519420bf95f4aa4da4b93) +++ firmware/App/Services/NVRecordsDD.h (.../NVRecordsDD.h) (revision 1be7dc9ec7ae5a6576a4c841e3b22ac77aea8db8) @@ -80,6 +80,7 @@ GET_CAL_FILL_CONDUCTIVITIES_RECORD, ///< Get fill conductivities record. GET_SYS_RECORD, ///< Get system record. GET_SRV_RECORD, ///< Get service record. + GET_INSTITUTIONAL_RECORD, ///< Get institutional record. GET_USAGE_RECORD, ///< Get usage record. NUM_OF_NV_DD_DATA ///< Number of non-volatile data. } NV_DATA_T; @@ -394,7 +395,7 @@ typedef struct { DD_ACID_BICARB_FILL_COND_VALUES_T fillCondValues[ NUM_OF_ACID_TYPE ][ NUM_OF_FILL_COND_TEST ]; ///< Acid and bicarb fill conductivity values. -} DD_CHEMICALS_FILL_COND_CAL_RECORD_T; +} DD_CONCENTRATES_COND_CAL_RECORD_T; /// DD systems record structure typedef struct @@ -406,6 +407,81 @@ U16 crc; ///< CRC for the DD system record structure. } DD_SYSTEM_RECORD_T; +/// DD service record structure +typedef struct +{ + U08 serviceLoc; ///< DD service location. + U32 lastServiceEpochDate; ///< DD last service date in epoch. + U32 serviceIntervalSeconds; ///< DD service interval in seconds. + U32 lastResetTimeEpoch; ///< Last time the record was reset in epoch. + U16 crc; ///< CRC for the DD service record structure. +} DD_SERVICE_RECORD_T; + +/// DD institutional record structure +typedef struct +{ + U32 minBloodFlowMLPM; ///< Min blood flow in mL/min. + U32 maxBloodFlowMLPM; ///< Max blood flow in mL/min. + U32 minDialysateFlowMLPM; ///< Min dialysate flow in mL/min. + U32 maxDialysateFlowMLPM; ///< Max dialysate flow in mL/min. + U32 minTxDurationMIN; ///< Min treatment duration in minutes. + U32 maxTxDurationMIN; ///< Max treatment duration in minutes. + U32 minStopHeparinDispBeforeTxEndMIN; ///< Min stop heparin dispense before treatment end in minutes. + U32 maxStopHeparinDispBeforeTxEndMIN; ///< Max stop heparin dispense before treatment end in minutes. + U32 minSalineBolusVolumeML; ///< Min saline bolus volume in milliliters. + U32 maxSalineBolusVolumeML; ///< Max saline bolus volume in milliliters. + F32 minDialysateTempC; ///< Min dialysate temperature in C. + F32 maxDialysateTempC; ///< Max dialysate temperature in C. + S32 minArtPressLimitWindowMMHG; ///< Min arterial pressure limit window in mmHg. + S32 maxArtPressLimitWindowMMHG; ///< Max arterial pressure limit window in mmHg. + S32 minVenPressLimitWindowMMHG; ///< Min venous pressure limit window in mmHg. + S32 maxVenPressLimitWindowMMHG; ///< Max venous pressure limit window in mmHg. + S32 minVenAsymPressLimitMMHG; ///< Min venous asymmetric pressure limit in mmHg. + S32 maxVenAsymPressLimitMMHG; ///< Max venous asymmetric pressure limit in mmHg. + F32 minUFVolumeL; ///< Min ultrafiltration volume in mL. + F32 maxUFVolumeL; ///< Max ultrafiltration volume in mL. + F32 minHeparinDispRateMLPHR; ///< Min heparin dispense rate in mL/hr. + F32 maxHeparinDispRateMLPHR; ///< Max heparin dispense rate in mL/hr. + F32 minHeparinBolusVolumeML; ///< Min heparin bolus volume in mL. + F32 maxHeparinBolusVolumeML; ///< Max heparin bolus volume in mL. + U32 enableChemicalDisinfect; ///< Enable/disable chemical disinfect. + U32 minRORejectionRatioPCT; ///< Min RO rejection ratio in percent. + F32 minInletWaterCondAlarmLimitUSPCM; ///< Min inlet water conductivity alarm limit in uS/cm. + U32 calibrationTime; ///< Calibration time in epoch. + U16 crc; ///< CRC of the institutional record. +} DD_INSTITUTIONAL_RECORD_T; + +typedef struct +{ + U32 minBloodFlowMLPM; ///< Min blood flow in mL/min. + U32 maxBloodFlowMLPM; ///< Max blood flow in mL/min. + U32 minDialysateFlowMLPM; ///< Min dialysate flow in mL/min. + U32 maxDialysateFlowMLPM; ///< Max dialysate flow in mL/min. + U32 minTxDurationMIN; ///< Min treatment duration in minutes. + U32 maxTxDurationMIN; ///< Max treatment duration in minutes. + U32 minStopHeparinDispBeforeTxEndMIN; ///< Min stop heparin dispense before treatment end in minutes. + U32 maxStopHeparinDispBeforeTxEndMIN; ///< Max stop heparin dispense before treatment end in minutes. + U32 minSalineBolusVolumeML; ///< Min saline bolus volume in milliliters. + U32 maxSalineBolusVolumeML; ///< Max saline bolus volume in milliliters. + F32 minDialysateTempC; ///< Min dialysate temperature in C. + F32 maxDialysateTempC; ///< Max dialysate temperature in C. + S32 minArtPressLimitWindowMMHG; ///< Min arterial pressure limit window in mmHg. + S32 maxArtPressLimitWindowMMHG; ///< Max arterial pressure limit window in mmHg. + S32 minVenPressLimitWindowMMHG; ///< Min venous pressure limit window in mmHg. + S32 maxVenPressLimitWindowMMHG; ///< Max venous pressure limit window in mmHg. + S32 minVenAsymPressLimitMMHG; ///< Min venous asymmetric pressure limit in mmHg. + S32 maxVenAsymPressLimitMMHG; ///< Max venous asymmetric pressure limit in mmHg. + F32 minUFVolumeL; ///< Min ultrafiltration volume in mL. + F32 maxUFVolumeL; ///< Max ultrafiltration volume in mL. + F32 minHeparinDispRateMLPHR; ///< Min heparin dispense rate in mL/hr. + F32 maxHeparinDispRateMLPHR; ///< Max heparin dispense rate in mL/hr. + F32 minHeparinBolusVolumeML; ///< Min heparin bolus volume in mL. + F32 maxHeparinBolusVolumeML; ///< Max heparin bolus volume in mL. + U32 enableChemicalDisinfect; ///< Enable/disable chemical disinfect. + U32 minRORejectionRatioPCT; ///< Min RO rejection ratio in percent. + F32 minInletWaterCondAlarmLimitUSPCM; ///< Min inlet water conductivity alarm limit in uS/cm. +} DD_INSTITUTIONAL_LOCAL_RECORD_T; + /// DD usage info structure. typedef struct { @@ -422,15 +498,6 @@ U16 crc; ///< CRC for the DD usage info structure. } DD_USAGE_INFO_RECORD_T; -/// DD service record structure -typedef struct -{ - U08 serviceLoc; ///< DD service location. - U32 lastServiceEpochDate; ///< DD last service date in epoch. - U32 serviceIntervalSeconds; ///< DD service interval in seconds. - U32 lastResetTimeEpoch; ///< Last time the record was reset in epoch. - U16 crc; ///< CRC for the DD service record structure. -} DD_SERVICE_RECORD_T; #pragma pack(pop) // ********** public function prototypes **********