Index: firmware/App/Services/FPGA.c =================================================================== diff -u -ra303cd4258157a8fbcbd8af4dd2bbaadec1a736c -rf068446fdb7889d320ddb6ffbd58f347ce0501e7 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision a303cd4258157a8fbcbd8af4dd2bbaadec1a736c) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision f068446fdb7889d320ddb6ffbd58f347ce0501e7) @@ -42,6 +42,10 @@ #define FPGA_PAGE_SIZE 256 #define FPGA_EXPECTED_ID 0x59 +#define FPGA_HEADER_START_ADDR 256 // update these after re-arranging w/ Randy +#define FPGA_BULK_READ_START_ADDR 262 +#define FPGA_BULK_WRITE_START_ADDR 2 + #define FPGA_WRITE_CMD_BUFFER_LEN (FPGA_PAGE_SIZE+8) #define FPGA_READ_CMD_BUFFER_LEN 8 #define FPGA_WRITE_RSP_BUFFER_LEN 8 @@ -50,15 +54,14 @@ #define FPGA_WRITE_CMD_CODE 0x55 #define FPGA_READ_CMD_CODE 0x5A #define FPGA_WRITE_CMD_ACK 0xA5 -#define FPGA_WRITE_CMD_NAK 0xAE #define FPGA_READ_CMD_ACK 0xAA -#define FPGA_READ_CMD_NAK 0xAF +#define FPGA_CMD_NAK 0xEE #define FPGA_CRC_LEN 2 #define FPGA_WRITE_CMD_HDR_LEN 4 #define FPGA_READ_CMD_HDR_LEN 4 -#define FPGA_WRITE_RSP_HDR_LEN 1 -#define FPGA_READ_RSP_HDR_LEN 1 +#define FPGA_WRITE_RSP_HDR_LEN 3 +#define FPGA_READ_RSP_HDR_LEN 3 #define SCI2_RECEIVE_DMA_REQUEST 28 #define SCI2_TRANSMIT_DMA_REQUEST 29 @@ -71,27 +74,43 @@ { U08 fpgaId; U08 fpgaRev; - U08 fpgaDiag; - U08 gap1; - U16 fpgaStatus; U16 fpgaControl; -} FPGA_HEADER_T; + U16 fpgaStatus; +} FPGA_HEADER_T; // read only on FPGA -typedef struct +typedef struct // TODO - add all sensor readings to this structure per FPGA register map { - U16 bloodLeak; - U32 adc1b; - U32 adc2b; - U32 dialysateTemp1; - U32 venousPressure; - U32 arterialPressure; - U32 adc1a; - U32 adc2a; - U32 dialysateTemp2; + U08 bloodFlowMeterDataPktCount; + U08 bloodFlowMeterSlowPktCounts; + U08 bloodFlowMeterDeviceStatus; + U08 bloodFlowMeterResponse; + F32 bloodFlowLast; + U08 dialysateFlowMeterDataPktCount; + U08 dialysateFlowMeterSlowPckCounts; + U08 dialysateFlowMeterDeviceStatus; + U08 dialysateFlowMeterResponse; + F32 dialysateFlowLast; + U08 bloodFlowMeterErrorCount; + U08 dialysateFlowMeterErrorCount; + U16 bloodOcclusionData; + U08 bloodOcclusionReadCount; + U08 bloodOcclusionErrorCount; + U16 dialysateInOcclusionData; + U08 dialysateInOcclusionReadCount; + U08 dialysateInOcclusionErrorCount; + U16 dialysateOutOcclusionData; + U08 dialysateOutOcclusionReadCount; + U08 dialysateOutOcclusionErrorCount; + U16 arterialPressureData; + U08 arterialPressureReadCount; + U08 arterialPressureErrorCount; + U16 dialysateTempPrimaryData; + U16 dialysateTempBackupData; } FPGA_SENSORS_T; -typedef struct +typedef struct // TODO - add all actuator set points to this structure per FPGA register map { + U08 bloodValveSetState; } FPGA_ACTUATORS_T; #pragma pack(pop) @@ -110,10 +129,10 @@ static BOOL fpgaReadCommandResponseReceived = FALSE; // FPGA comm buffers -static U08 fpgaWriteCmdBuffer[FPGA_WRITE_CMD_BUFFER_LEN]; -static U08 fpgaReadCmdBuffer[FPGA_READ_CMD_BUFFER_LEN]; -static U08 fpgaWriteResponseBuffer[FPGA_WRITE_RSP_BUFFER_LEN]; -static U08 fpgaReadResponseBuffer[FPGA_READ_RSP_BUFFER_LEN]; +static U08 fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_BUFFER_LEN ]; +static U08 fpgaReadCmdBuffer[ FPGA_READ_CMD_BUFFER_LEN ]; +static U08 fpgaWriteResponseBuffer[ FPGA_WRITE_RSP_BUFFER_LEN ]; +static U08 fpgaReadResponseBuffer[ FPGA_READ_RSP_BUFFER_LEN ]; // DMA control records static g_dmaCTRL fpgaDMAWriteControlRecord; @@ -363,7 +382,7 @@ default: if ( fpgaState >= NUM_OF_FPGA_STATES ) { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_INVALID_IN_STATE, fpgaState ) } else { @@ -413,7 +432,7 @@ default: if ( fpgaState >= NUM_OF_FPGA_STATES ) { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_INVALID_OUT_STATE, fpgaState ) } else { @@ -439,13 +458,13 @@ U16 crc; // construct read command to read 3 registers starting at address 0 - fpgaReadCmdBuffer[0] = FPGA_READ_CMD_CODE; - fpgaReadCmdBuffer[1] = 0x00; // start at FPGA address 0 - fpgaReadCmdBuffer[2] = 0x00; - fpgaReadCmdBuffer[3] = sizeof(FPGA_HEADER_T); + fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; + fpgaReadCmdBuffer[ 1 ] = 0x00; // start at FPGA address 0 + fpgaReadCmdBuffer[ 2 ] = 0x00; + fpgaReadCmdBuffer[ 3 ] = sizeof(FPGA_HEADER_T); crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); - fpgaReadCmdBuffer[4] = GET_LSB_OF_WORD( crc ); - fpgaReadCmdBuffer[5] = GET_MSB_OF_WORD( crc ); + fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); + fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); // prep DMA for sending the read cmd and receiving the response fpgaReadCommandInProgress = TRUE; setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_HEADER_T) + FPGA_CRC_LEN ); @@ -474,19 +493,18 @@ if ( TRUE == fpgaReadCommandResponseReceived ) { // did FPGA Ack the read command? - if ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ) + if ( fpgaReadResponseBuffer[ 0 ] == FPGA_READ_CMD_ACK ) { U32 rspSize = FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_HEADER_T); U32 crcPos = rspSize; - U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[crcPos+1], fpgaReadResponseBuffer[crcPos] ); + U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); // does the FPGA response CRC check out? if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) -// if ( 1 ) // TODO - remove when FPGA CRCs are implemented { fpgaCommRetryCount = 0; // capture the read values - memcpy( &fpgaHeader, &fpgaReadResponseBuffer[1], sizeof(FPGA_HEADER_T) ); + memcpy( &fpgaHeader, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( FPGA_HEADER_T ) ); result = FPGA_STATE_WRITE_ALL_ACTUATORS; } else @@ -526,29 +544,28 @@ U16 crc; // construct bulk write command to write actuator data registers starting at address 3 (TODO - change address later) - fpgaWriteCmdBuffer[0] = FPGA_WRITE_CMD_CODE; - fpgaWriteCmdBuffer[1] = 0x08; // start at FPGA address 8 - fpgaWriteCmdBuffer[2] = 0x00; - fpgaWriteCmdBuffer[3] = 1; // TODO - replace 1 with sizeof(FPGA_ACTUATORS_T) -// memcpy( &(fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN]), &fpgaActuatorSetPoints, sizeof(FPGA_ACTUATORS_T) ); - fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN] = 99; // TODO - remove and replace with memcpy above - crc = crc16( fpgaWriteCmdBuffer, FPGA_WRITE_CMD_HDR_LEN+1 ); // TODO - replace +1 with +sizeof(FPGA_ACTUATORS_T) - fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN+1] = GET_LSB_OF_WORD( crc ); // TODO - replace +1 with +sizeof(FPGA_ACTUATORS_T) - fpgaWriteCmdBuffer[FPGA_WRITE_CMD_HDR_LEN+1+1] = GET_MSB_OF_WORD( crc ); // TODO - replace +1 with +sizeof(FPGA_ACTUATORS_T) + fpgaWriteCmdBuffer[ 0 ] = FPGA_WRITE_CMD_CODE; + fpgaWriteCmdBuffer[ 1 ] = 0x08; // start at FPGA address 8 + fpgaWriteCmdBuffer[ 2 ] = 0x00; + fpgaWriteCmdBuffer[ 3 ] = sizeof(FPGA_ACTUATORS_T); + memcpy( &( fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN ] ), &fpgaActuatorSetPoints, sizeof( FPGA_ACTUATORS_T ) ); + crc = crc16( fpgaWriteCmdBuffer, FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) ); + fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) ] = GET_MSB_OF_WORD( crc ); + fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) + 1 ] = GET_LSB_OF_WORD( crc ); // construct bulk read command to read sensor data registers starting at address 8 - fpgaReadCmdBuffer[0] = FPGA_READ_CMD_CODE; - fpgaReadCmdBuffer[1] = 0x08; // start at FPGA address 8 - fpgaReadCmdBuffer[2] = 0x00; - fpgaReadCmdBuffer[3] = sizeof(FPGA_SENSORS_T); + fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; + fpgaReadCmdBuffer[ 1 ] = 0x08; // start at FPGA address 0x108 (264) + fpgaReadCmdBuffer[ 2 ] = 0x01; + fpgaReadCmdBuffer[ 3 ] = sizeof(FPGA_SENSORS_T); crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); - fpgaReadCmdBuffer[4] = GET_LSB_OF_WORD( crc ); - fpgaReadCmdBuffer[5] = GET_MSB_OF_WORD( crc ); + fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); + fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); // prep DMA for sending the bulk write cmd and receiving its response - setupDMAForWriteCmd( FPGA_WRITE_CMD_HDR_LEN + 1 + FPGA_CRC_LEN ); // TODO s/b sizeof(FPGA_ACTUATORS_T) instead of 1 - setupDMAForWriteResp( FPGA_WRITE_RSP_HDR_LEN ); + setupDMAForWriteCmd( FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) + FPGA_CRC_LEN ); + setupDMAForWriteResp( FPGA_WRITE_RSP_HDR_LEN + FPGA_CRC_LEN ); // prep DMA for sending the bulk read cmd and receiving its response setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); - setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_SENSORS_T) + FPGA_CRC_LEN ); + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof( FPGA_SENSORS_T ) + FPGA_CRC_LEN ); // set fpga comm flags for bulk write cmd and follow-up bulk read command fpgaWriteCommandInProgress = TRUE; fpgaBulkWriteAndReadInProgress = TRUE; @@ -574,7 +591,7 @@ FPGA_STATE_T result = FPGA_STATE_WRITE_ALL_ACTUATORS; // check bulk write command success - if ( ( FALSE == fpgaWriteCommandResponseReceived ) || ( fpgaWriteResponseBuffer[0] != FPGA_WRITE_CMD_ACK ) ) + if ( ( FALSE == fpgaWriteCommandResponseReceived ) || ( fpgaWriteResponseBuffer[ 0 ] != FPGA_WRITE_CMD_ACK ) ) { fpgaCommRetryCount++; } @@ -583,19 +600,18 @@ if ( TRUE == fpgaReadCommandResponseReceived ) { // did FPGA Ack the read command? - if ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ) + if ( fpgaReadResponseBuffer[ 0 ] == FPGA_READ_CMD_ACK ) { U32 rspSize = FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_SENSORS_T); U32 crcPos = rspSize; - U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[crcPos+1], fpgaReadResponseBuffer[crcPos] ); + U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); // does the FPGA response CRC check out? if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) -// if ( 1 ) // TODO - remove when FPGA CRCs are implemented { fpgaCommRetryCount = 0; // capture the read values - memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[1], sizeof(FPGA_SENSORS_T) ); + memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( FPGA_SENSORS_T ) ); result = FPGA_STATE_WRITE_ALL_ACTUATORS; } else // bad CRC @@ -630,13 +646,22 @@ *************************************************************************/ SELF_TEST_STATUS_T execFPGATest( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; + SELF_TEST_STATUS_T result; // check FPGA reported correct ID +#ifndef RM46_EVAL_BOARD_TARGET if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) +#else + if ( 1 ) +#endif { result = SELF_TEST_STATUS_PASSED; } + else + { + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_FPGA_POST_TEST_FAILED, (U32)fpgaHeader.fpgaId ) + } return result; } @@ -660,7 +685,7 @@ } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_WRITE_CMD_TOO_MUCH_DATA, bytes2Transmit ) } } @@ -700,7 +725,7 @@ } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_WRITE_RSP_TOO_MUCH_DATA, bytes2Receive ) } } @@ -740,7 +765,7 @@ } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_READ_CMD_TOO_MUCH_DATA, bytes2Transmit ) } } @@ -780,7 +805,7 @@ } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_READ_RSP_TOO_MUCH_DATA, bytes2Receive ) } } @@ -832,51 +857,147 @@ } /************************************************************************* - * @brief getFPGADiag - * The getFPGADiag function gets the version read from the diagnostic register \n + * @brief getFPGAStatus + * The getFPGAStatus function gets the version read from the diagnostic register \n * of the FPGA. * @details * Inputs : fpgaHeader * Outputs : none * @param none - * @return fpgaDiag + * @return fpgaHeader.fpgaStatus *************************************************************************/ -U08 getFPGADiag( void ) +U16 getFPGAStatus( void ) { - return fpgaHeader.fpgaDiag; + return fpgaHeader.fpgaStatus; } /************************************************************************* - * @brief getFPGAStatus - * The getFPGAStatus function gets the version read from the diagnostic register \n - * of the FPGA. + * @brief getFPGADiag + * The getFPGADiag function sets the diagnostic register of the FPGA. * @details * Inputs : fpgaHeader * Outputs : none + * @param ctrl : value to write to diagnostic register + * @return none + *************************************************************************/ +void setFPGAControl( U16 ctrl ) +{ + fpgaHeader.fpgaControl = ctrl; +} + +/************************************************************************* + * @brief getFPGABloodFlow + * The getFPGABloodFlow function gets the latest blood flow reading. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none * @param none - * @return fpgaDiag + * @return last blood flow reading *************************************************************************/ -U16 getFPGAStatus( void ) +F32 getFPGABloodFlow( void ) { - return fpgaHeader.fpgaStatus; + return fpgaSensorReadings.bloodFlowLast; } /************************************************************************* - * @brief getFPGADiag - * The getFPGADiag function gets the version read from the diagnostic register \n - * of the FPGA. + * @brief getFPGADialysateFlow + * The getFPGADialysateFlow function gets the latest dialysate flow reading. * @details - * Inputs : fpgaHeader + * Inputs : fpgaSensorReadings * Outputs : none * @param none - * @return fpgaDiag + * @return last dialysate flow reading *************************************************************************/ -void setFPGAControl( U16 ctrl ) +F32 getFPGADialysateFlow( void ) { - fpgaHeader.fpgaControl = ctrl; + return fpgaSensorReadings.dialysateFlowLast; } /************************************************************************* + * @brief getFPGABloodPumpOcclusion + * The getFPGABloodPumpOcclusion function gets the latest blood occlusion reading. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @param none + * @return last blood occlusion reading + *************************************************************************/ +U16 getFPGABloodPumpOcclusion( void ) +{ + return fpgaSensorReadings.bloodOcclusionData; +} + +/************************************************************************* + * @brief getFPGADialInPumpOcclusion + * The getFPGADialInPumpOcclusion function gets the latest dialysate \n + * inlet occlusion reading. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @param none + * @return last dialysate inlet occlusion reading + *************************************************************************/ +U16 getFPGADialInPumpOcclusion( void ) +{ +#ifdef DEBUG_ENABLED +// { +// // TODO - temporary debug code - remove later +// char debugOccStr[ 60 ]; +// S32 dat = fpgaSensorReadings.dialysateInOcclusionData; +// S32 rct = fpgaSensorReadings.dialysateInOcclusionReadCount; +// S32 ect = fpgaSensorReadings.dialysateInOcclusionErrorCount; +// +// sprintf( debugOccStr, "Data %5d Reads %5d Errors %5d\n", dat, rct, ect ); +// sendDebugData( (U08*)debugOccStr, strlen(debugOccStr) ); +// } +#endif + return fpgaSensorReadings.dialysateInOcclusionData; +} + +/************************************************************************* + * @brief getFPGADialOutPumpOcclusion + * The getFPGADialOutPumpOcclusion function gets the latest dialysate \n + * outlet occlusion reading. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @param none + * @return last dialysate outlet occlusion reading + *************************************************************************/ +U16 getFPGADialOutPumpOcclusion( void ) +{ + return fpgaSensorReadings.dialysateOutOcclusionData; +} + +/************************************************************************* + * @brief getFPGAArterialPressure + * The getFPGAArterialPressure function gets the latest arterial pressure reading. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @param none + * @return last arterial pressure reading + *************************************************************************/ +U16 getFPGAArterialPressure( void ) +{ + return fpgaSensorReadings.arterialPressureData; +} + +/************************************************************************* + * @brief getFPGAVenousPressure + * The getFPGAVenousPressure function gets the venous arterial pressure reading. + * @details + * Inputs : fpgaSensorReadings + * Outputs : none + * @param none + * @return last venous pressure reading + *************************************************************************/ +U16 getFPGAVenousPressure( void ) +{ + return 0; // TODO - return reading when available +} + +/************************************************************************* * @brief consumeUnexpectedData * The consumeUnexpectedData function checks to see if a byte is sitting in \n * the SCI2 received data register. @@ -891,7 +1012,7 @@ // clear any errors sciRxError( scilinREG ); // if a byte is pending read, read it - if ( 0 != sciIsRxReady( scilinREG ) ) + if ( sciIsRxReady( scilinREG ) != 0 ) { sciReceiveByte( scilinREG ); }