Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r47c41046beba8affaaaa13a4f222a7b99bd193f1 -r604d8aaceeb8e0b650ac2054644333fc7717bb51 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 47c41046beba8affaaaa13a4f222a7b99bd193f1) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 604d8aaceeb8e0b650ac2054644333fc7717bb51) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * -* @file SystemComm.c +* @file SystemComm.c * -* @author (last) Quang Nguyen -* @date (last) 26-Aug-2020 +* @author (last) Dara Navaei +* @date (last) 31-Mar-2022 * -* @author (original) Dara Navaei -* @date (original) 05-Nov-2019 +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 * ***************************************************************************/ @@ -37,14 +37,8 @@ // ********** private definitions ********** #define NUM_OF_CAN_OUT_BUFFERS 5 ///< Number of CAN buffers for transmit -#define NUM_OF_CAN_IN_BUFFERS 7 ///< Number of CAN buffers for receiving -#ifndef DEBUG_ENABLED - #define NUM_OF_MSG_IN_BUFFERS 7 ///< Number of Msg buffers for receiving -#else - #define NUM_OF_MSG_IN_BUFFERS 8 - #define SCI1_RECEIVE_DMA_REQUEST 30 - #define SCI1_TRANSMIT_DMA_REQUEST 31 -#endif +#define NUM_OF_CAN_IN_BUFFERS 7 ///< Number of CAN buffers for receiving +#define NUM_OF_MSG_IN_BUFFERS 7 ///< Number of Msg buffers for receiving #define CAN_XMIT_PACKET_TIMEOUT_MS 200 ///< if transmitted CAN frame does not cause a transmit complete interrupt within this time, re-send or move on #define MAX_XMIT_RETRIES 5 ///< maximum number of retries on no transmit complete interrupt timeout @@ -54,9 +48,9 @@ #define MAX_COMM_CRC_FAILURES 5 ///< maximum number of CRC errors within window period before alarm #define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window -#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 ) ///< maximum time for a Denali message that requires ACK to be ACK'd -#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm -#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time +#define MSG_NOT_ACKED_TIMEOUT_MS 150 ///< maximum time for a Denali message that requires ACK to be ACK'd +#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm +#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time #pragma pack(push, 1) @@ -96,9 +90,6 @@ COMM_BUFFER_IN_CAN_UI_2_DG, COMM_BUFFER_IN_CAN_UI_BROADCAST, COMM_BUFFER_IN_CAN_PC, -#ifdef DEBUG_ENABLED - COMM_BUFFER_IN_UART_PC -#endif }; static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ]; ///< Keep last packet sent on CAN bus in case we need to re-send. @@ -109,18 +100,9 @@ static volatile BOOL dgIsOnlyCANNode = TRUE; ///< flag indicating whether DG is alone on CAN bus. static U32 canXmitRetryCtr = 0; ///< counter for CAN transmit retries. -static volatile BOOL hdIsCommunicating = FALSE; ///< has HD sent a message since last check +static OVERRIDE_U32_T hdCommunicationStatus = {0, 0, 0, 0}; ///< has HD sent a message since last check static volatile U32 timeOfLastHDCheckIn = 0; ///< last time we received an HD broadcast -#ifdef DEBUG_ENABLED - // debug buffers - static U08 pcXmitPacket[ 1024 ]; - static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - // DMA control records - static g_dmaCTRL pcDMAXmitControlRecord; - static g_dmaCTRL pcDMARecvControlRecord; -#endif - // ********** private function prototypes ********** static void clearCANXmitBuffers( void ); @@ -140,11 +122,6 @@ static BOOL matchACKtoPendingACKList( S16 seqNo ); static void checkPendingACKList( void ); -#ifdef DEBUG_ENABLED - static void initUARTAndDMA( void ); - static U32 transmitNextUARTPacket( void ); -#endif - /*********************************************************************//** * @brief * The initSystemComm function initializes the SystemComm module. @@ -156,11 +133,6 @@ { U32 i; -#ifdef DEBUG_ENABLED - // initialize UART and DMA for PC communication - initUARTAndDMA(); -#endif - // initialize bad message CRC time windowed count initTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC, MAX_COMM_CRC_FAILURES, MAX_COMM_CRC_FAILURE_WINDOW_MS ); @@ -181,7 +153,7 @@ *************************************************************************/ BOOL isHDCommunicating( void ) { - return hdIsCommunicating; + return getU32OverrideValue(&hdCommunicationStatus); } /*********************************************************************//** @@ -261,14 +233,6 @@ } // end - pending xmit timeout? } // end - transmit in progress or not } // end - DG not alone on CAN bus - -#ifdef DEBUG_ENABLED - // if UART transmitter is idle, start transmitting any pending packets - if ( FALSE == isSCI1DMATransmitInProgress() ) - { - transmitNextUARTPacket(); - } -#endif } /*********************************************************************//** @@ -317,108 +281,8 @@ } } -#ifdef DEBUG_ENABLED /*********************************************************************//** * @brief - * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive - * packet completed interrupt. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -void handleUARTMsgRecvPacketInterrupt( void ) -{ - // buffer received packet - addToCommBuffer( COMM_BUFFER_IN_UART_PC, pcRecvPacket, PC_MESSAGE_PACKET_SIZE ); - // prepare to receive next packet - dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord ); - dmaSetChEnable( DMA_CH1, DMA_HW ); - setSCI1DMAReceiveInterrupt(); -} - -/*********************************************************************//** - * @brief - * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit - * packet completed interrupt. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -void handleUARTMsgXmitPacketInterrupt( void ) -{ - U32 bytesXmitted = transmitNextUARTPacket(); - - if ( 0 == bytesXmitted ) - { - signalSCI1XmitsCompleted(); - } -} - -/*********************************************************************//** - * @brief - * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA - * to go with it for PC communication. - * @details Inputs: none - * @details Outputs: SCI1 and DMA initialized - * @return none - *************************************************************************/ -static void initUARTAndDMA( void ) -{ - // Enable DMA block transfer complete interrupts - dmaEnableInterrupt( DMA_CH1, BTC ); - dmaEnableInterrupt( DMA_CH3, BTC ); - // assign DMA channels to h/w DMA requests - dmaReqAssign( DMA_CH1, SCI1_RECEIVE_DMA_REQUEST ); - dmaReqAssign( DMA_CH3, SCI1_TRANSMIT_DMA_REQUEST ); - // set DMA channel priorities - dmaSetPriority( DMA_CH1, HIGHPRIORITY ); - dmaSetPriority( DMA_CH3, LOWPRIORITY ); - - // initialize PC DMA Transmit Control Record - pcDMAXmitControlRecord.PORTASGN = 4; // port B (only choice per datasheet) - pcDMAXmitControlRecord.DADD = (U32)(&(sciREG->TD)); // dest. is SCI2 xmit register - pcDMAXmitControlRecord.SADD = (U32)pcXmitPacket; // source - pcDMAXmitControlRecord.CHCTRL = 0; // no chaining - pcDMAXmitControlRecord.ELCNT = 1; // frame is 1 element - pcDMAXmitControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames - pcDMAXmitControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte - pcDMAXmitControlRecord.WRSIZE = ACCESS_8_BIT; // - pcDMAXmitControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer - pcDMAXmitControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed - pcDMAXmitControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment - pcDMAXmitControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - pcDMAXmitControlRecord.ELSOFFSET = 0; // not used - pcDMAXmitControlRecord.ELDOFFSET = 0; // not used - pcDMAXmitControlRecord.FRSOFFSET = 0; // not used - pcDMAXmitControlRecord.FRDOFFSET = 0; // not used - - // initialize PC DMA Receipt Control Record - pcDMARecvControlRecord.PORTASGN = 4; // port B (only choice per datasheet) - pcDMARecvControlRecord.SADD = (U32)(&(sciREG->RD)); // source is SCI2 recv register - pcDMARecvControlRecord.DADD = (U32)pcRecvPacket; // transfer destination address - pcDMARecvControlRecord.CHCTRL = 0; // no chaining - pcDMARecvControlRecord.ELCNT = 1; // frame is 1 element - pcDMARecvControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames - pcDMARecvControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte - pcDMARecvControlRecord.WRSIZE = ACCESS_8_BIT; // - pcDMARecvControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer - pcDMARecvControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed - pcDMARecvControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment - pcDMARecvControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - pcDMARecvControlRecord.ELDOFFSET = 0; // not used - pcDMARecvControlRecord.ELSOFFSET = 0; // not used - pcDMARecvControlRecord.FRDOFFSET = 0; // not used - pcDMARecvControlRecord.FRSOFFSET = 0; // not used - - // initiate PC packet receiving readiness via DMA - dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord ); - dmaSetChEnable( DMA_CH1, DMA_HW ); - setSCI1DMAReceiveInterrupt(); -} -#endif - -/*********************************************************************//** - * @brief * The isCANBoxForXmit function determines whether a given CAN message box * is configured for transmit. * @details Inputs: CAN_OUT_BUFFERS[] @@ -566,40 +430,6 @@ return result; } -#ifdef DEBUG_ENABLED -/*********************************************************************//** - * @brief - * The transmitNextUARTPacket function sets up and initiates a DMA transmit - * of the next packet pending transmit (if any) via UART. - * @details Inputs: Output UART Comm Buffer(s) - * @details Outputs: UART DMA transmit initiated. - * @return number of bytes transmitted - *************************************************************************/ -static U32 transmitNextUARTPacket( void ) -{ - U32 result = 0; - U32 dataPend = numberOfBytesInCommBuffer( COMM_BUFFER_OUT_UART_PC ); - - if ( dataPend > 0 ) - { - result = getFromCommBuffer( COMM_BUFFER_OUT_UART_PC, pcXmitPacket, dataPend ); - - // if there's data to transmit, transmit it - if ( result > 0 ) - { - signalSCI1XmitsInitiated(); - pcDMAXmitControlRecord.FRCNT = result; // set DMA transfer size - dmaSetCtrlPacket( DMA_CH3, pcDMAXmitControlRecord ); - dmaSetChEnable( DMA_CH3, DMA_HW ); - setSCI1DMATransmitInterrupt(); - } - } - - return result; -} -#endif - - /************************************************************************* ********************** RECEIVE SUPPORT FUNCTIONS ************************* *************************************************************************/ @@ -666,7 +496,7 @@ // if message from HD broadcast channel, update HD comm status if ( COMM_BUFFER_IN_CAN_HD_BROADCAST == MSG_IN_BUFFERS[ i ] ) { - hdIsCommunicating = TRUE; + hdCommunicationStatus.data = (U32)TRUE; timeOfLastHDCheckIn = getMSTimerCount(); } } @@ -790,7 +620,7 @@ if ( message.crc == crc8( (U08*)(&message), sizeof(MESSAGE_HEADER_T) + message.msg.hdr.payloadLen ) ) { // if ACK, mark pending message ACK'd - if ( MSG_ID_ACK == message.msg.hdr.msgID ) + if ( MSG_ID_ACK_MESSAGE_THAT_REQUIRES_ACK == message.msg.hdr.msgID ) { matchACKtoPendingACKList( message.msg.hdr.seqNo ); } @@ -824,8 +654,8 @@ { if ( TRUE == didTimeout( timeOfLastHDCheckIn, HD_COMM_TIMEOUT_IN_MS ) ) { - hdIsCommunicating = FALSE; - activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT ); + hdCommunicationStatus.data = FALSE; + //activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT ); } } @@ -950,7 +780,9 @@ U16 msgID; memcpy( &msgID, &pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); +#ifndef DISABLE_ACK_ALARM SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID ); +#endif pendingAckList[ i ].used = FALSE; // take pending message off of list } } @@ -1041,6 +873,14 @@ handleDGServiceScheduleRequest( message ); break; + case MSG_ID_HD_REQUEST_DG_CONCENTRATE_MIXING_RATIOS: + handleDGSendConcentrateMixingRatios( message ); + break; + + case MSG_ID_DG_SCHEDULED_RUNS_INFO: + handleDGScheduledRunsRequest( message ); + break; + // NOTE: This case must be last case MSG_ID_DG_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); @@ -1052,7 +892,8 @@ } // handle any test messages if tester has logged in successfully - if ( ( msgID > MSG_ID_FIRST_DG_TESTER_MESSAGE ) && ( msgID <= END_OF_MSG_IDS ) && ( TRUE == isTestingActivated() ) ) + // NOTE: END_OF_MSG_IDS = 65536 which is out of the range of a U16 so it is subtracted by 1. This is unreachable in development testing + if ( ( msgID > MSG_ID_FIRST_DG_TESTER_MESSAGE ) && ( msgID <= END_OF_MSG_IDS - 1 ) && ( TRUE == isTestingActivated() ) ) { switch ( msgID ) { @@ -1092,14 +933,22 @@ handleTestROMeasuredFlowOverrideRequest( message ); break; + case MSG_ID_DIALYSATE_MEASURED_FLOW_OVERRIDE: + handleTestDialysateMeasuredFlowOverrideRequest( message ); + break; + case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: handleTestROPumpDataBroadcastIntervalOverrideRequest( message ); break; - case MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE: - handleTestDrainPumpRPMOverrideRequest( message ); + case MSG_ID_DIALYSATE_FLOW_SEND_INTERVAL_OVERRIDE: + handleTestDialysateFlowDataBroadcastIntervalOverrideRequest( message ); break; + case MSG_ID_DRAIN_PUMP_SET_RPM: + handleTestSetDrainPumpRPM( message ); + break; + case MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: handleTestDrainPumpDataBroadcastIntervalOverrideRequest( message ); break; @@ -1117,23 +966,23 @@ break; case MSG_ID_TEMPERATURE_SENSORS_VALUE_OVERRIDE: - handleTestTemperatureSensorsOverrideRequest ( message ); + handleTestTemperatureSensorsOverrideRequest( message ); break; case MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE: - handleTestTemperatureSensorsDataPublishOverrideRequest ( message ); + handleTestTemperatureSensorsDataPublishOverrideRequest( message ); break; case MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE: - handleTestHeatersDataPublishOverrideRequest ( message ); + handleTestHeatersDataPublishOverrideRequest( message ); break; case MSG_ID_CONDUCTIVITY_OVERRIDE: - handleTestSetConductivityOverrideRequest ( message ); + handleTestSetConductivityOverrideRequest( message ); break; case MSG_ID_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE: - handleTestSetConductivityDataPublishIntervalOverrideRequest ( message ); + handleTestSetConductivityDataPublishIntervalOverrideRequest( message ); break; case MSG_ID_DG_ACCEL_OVERRIDE: @@ -1156,8 +1005,8 @@ handleTestMonitoredVoltageOverrideRequest( message ); break; - case MSG_ID_DRAIN_PUMP_SET_DELTA_PRESSURE_OVERRIDE: - handleSetDrainPumpDeltaPressureOverrideRequest( message ); + case MSG_ID_DRAIN_PUMP_TARGET_OUTLET_PRESSURE: + handleSetDrainPumpTargetOutletPressure( message ); break; case MSG_ID_DG_SWITCHES_STATUS_OVERRIDE: @@ -1205,10 +1054,10 @@ break; case MSG_ID_DG_RO_FLOW_RATE_OVERRIDE: - handleTestMeasuredROFlowRateOverride( message ); + handleTestROMeasuredFlowOverrideRequest( message ); break; - case MSG_ID_DG_RO_PUMP_TARGET_FLOW_OVERRIDE: + case MSG_ID_DG_SET_RO_PUMP_TARGET_FLOW: handleTestROPumpTargetFlowOverride( message ); break; @@ -1273,14 +1122,115 @@ break; case MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE: - handleFilterFlushTimePeriodOverride(message); + handleFilterFlushTimePeriodOverride( message ); break; + case MSG_ID_DG_FANS_RPM_OVERRIDE: + handleFansRPMOverride( message ); + break; + + case MSG_ID_DG_STOP_RTC_CLOCK: + handleStopDGRTCClock( message ); + break; + + case MSG_ID_DG_DRAIN_PUMP_MEASURED_RPM_OVERRIDE: + handleSetDrainPumpMeasuredRPMOverrideRequest( message ); + break; + + case MSG_ID_DG_BLOCK_MESSAGE_TRANSMISSION: + handleTestBlockMessagesRequest( message ); + break; + + case MSG_ID_DG_SUPER_CLEAR_ALARMS_CMD: + handleTestSuperClearAlarmsRequest( message ); + break; + + case MSG_ID_DG_ALARM_INFO_SEND_INTERVAL_OVERRIDE: + handleTestAlarmInfoSendIntervalOverrideRequest( message ); + break; + + case MSG_ID_DG_FAN_RPM_ALARM_START_TIME_OFFSET_OVERRIDE: + handleTestFansRPMAlarmStartTimeOffsetOverrideRequest( message ); + break; + + case MSG_ID_DG_USED_ACID_VOLUME_ML_OVERRIDE: + handleTestUsedAcidVolumeMLOverrideRequest( message ); + break; + + case MSG_ID_DG_USED_BICARB_VOLUME_ML_OVERRIDE: + handleTestUsedBicarbVolumeMLOverrideRequest( message ); + break; + + case MSG_ID_DG_GET_SW_CONFIG_RECORD: + handleGetDGSoftwareConfigRecord( message ); + break; + + case MSG_ID_DG_SET_SW_CONFIG_RECORD: + handleSetDGSoftwareConfigRecord( message ); + break; + + case MSG_ID_DG_FANS_DUTY_CYCLE_OVERRIDE: + handleSetFansDutyCycleOverrideRequest( message ); + break; + + case MSG_ID_DG_HD_COMMUNICATION_STATUS_OVERRIDE: + handleTestHDCommunicationStatusOverrideRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; } } } + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + +/*********************************************************************//** + * @brief + * The testSetHDCommunicationStatus function sets the override + * of the HD communication status. + * @details Inputs: none + * @details Outputs: hdCommunicationStatus + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testSetHDCommunicationStatus( U32 value ) +{ + BOOL result = FALSE; + + if (TRUE == isTestingActivated() ) + { + result = TRUE; + hdCommunicationStatus.ovData = value; + hdCommunicationStatus.override = OVERRIDE_KEY; + + } + return result; +} + +/*********************************************************************//** + * @brief + * The testResetHDCommuncationStatus function resets the override + * of the HD communication status. + * @details Inputs: none + * @details Outputs: hdCommunicationStatus + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetHDCommuncationStatus( void ) +{ + BOOL result = FALSE; + + if (TRUE == isTestingActivated() ) + { + result = TRUE; + hdCommunicationStatus.override = OVERRIDE_RESET; + hdCommunicationStatus.ovData = hdCommunicationStatus.ovInitData; + + } + return result; +} + /**@}*/