Index: firmware/.launches/HD.launch =================================================================== diff -u -r9d4666bf3064df18a6d935125d7a69e4e8234e84 -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/.launches/HD.launch (.../HD.launch) (revision 9d4666bf3064df18a6d935125d7a69e4e8234e84) +++ firmware/.launches/HD.launch (.../HD.launch) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -7,7 +7,7 @@ - + Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rd4850547b287cc1f94ea3617a1902c5278ea86b4 -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d4850547b287cc1f94ea3617a1902c5278ea86b4) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -21,6 +21,10 @@ #include "can.h" #include "etpwm.h" +// TODO - test includes - remove later +#include "DialInFlow.h" +#include "PresOccl.h" + #include "FPGA.h" #include "InternalADC.h" #include "OperationModes.h" @@ -799,28 +803,29 @@ static void publishBloodFlowData( void ) { // publish blood flow data on interval +#ifndef READ_FPGA_ASYNC_DATA if ( ++bloodFlowDataPublicationTimerCounter >= getPublishBloodFlowDataInterval() ) +#endif { S32 flowStPt = (S32)getTargetBloodFlowRate(); -#ifndef SHOW_RAW_FLOW_VALUES F32 measFlow = getMeasuredBloodFlowRate(); -#else - F32 measFlow = getFPGABloodFlow(); -#endif F32 measRotSpd = getMeasuredBloodPumpRotorSpeed(); F32 measSpd = getMeasuredBloodPumpSpeed(); F32 measMCSpd = getMeasuredBloodPumpMCSpeed(); F32 measMCCurr = getMeasuredBloodPumpMCCurrent(); F32 pumpPWMPctDutyCycle = bloodPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; -#ifdef DEBUG_ENABLED +#ifdef READ_FPGA_ASYNC_DATA // TODO - temporary debug code - remove later char debugFlowStr[ 256 ]; -// F32 measFlowRaw = getFPGABloodFlow(); -// F32 dialFlow = getMeasuredDialInFlowRate(); -// F32 dialFlowRaw = getFPGADialysateFlow(); - sprintf( debugFlowStr, "Tgt:%5d, Flow:%5d, Speed-MC:%5d RPM, Speed:%5d RPM, Rotor:%5d RPM, Curr:%5d mA, PWM:%5d \n", flowStPt, (S32)measFlow, (S32)measMCSpd, (S32)measSpd, (S32)measRotSpd, (S32)measMCCurr, (S32)pumpPWMPctDutyCycle ); -// sprintf( debugFlowStr, "Blood: %5d, %5d Dial: %5d, %5d\n", (S32)measFlowRaw, (S32)measFlow, (S32)dialFlowRaw, (S32)dialFlow ); + F32 measFlowSig = getFPGABloodFlowSignalStrength() * 10000.0; + F32 dialFlow = getMeasuredDialInFlowRate(); + F32 dialFlowSig = getFPGADialysateFlowSignalStrength() * 10000.0; + F32 bldOccl = getMeasuredBloodPumpOcclusion(); + F32 dpiOccl = getMeasuredDialInPumpOcclusion(); + F32 dpoOccl = getMeasuredDialOutPumpOcclusion(); + + sprintf( debugFlowStr, "Blood: %5d, %5d, %5d Dial-I: %5d, %5d, %5d Dial-O: %5d\n", (S32)measFlowSig, (S32)measFlow, (S32)bldOccl, (S32)dialFlowSig, (S32)dialFlow, (S32)dpiOccl, (S32)dpoOccl ); sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); #endif broadcastBloodFlowData( flowStPt, measFlow, measRotSpd, measSpd, measMCSpd, measMCCurr, pumpPWMPctDutyCycle ); Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r2112e3143003eaf9584d4be068f7ca89b33c941a -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 2112e3143003eaf9584d4be068f7ca89b33c941a) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -18,6 +18,7 @@ #include "ModeTreatment.h" #include "OperationModes.h" #include "SystemCommMessages.h" +#include "Timers.h" #include "DGInterface.h" /** @@ -33,7 +34,7 @@ #define DRAIN_RESERVOIR_TO_VOLUME_ML 200 //100 ///< Drain reservoir to this volume (in mL) during treatment. #define FILL_RESERVOIR_TO_VOLUME_ML 1500 ///< Fill reservoir to this volume (in mL) during treatment. -#define RESERVOIR_SETTLE_TIME_MS 3000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). +#define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States @@ -176,7 +177,7 @@ break; case TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE: - if ( DG_MODE_CIRC == dgOpMode ) + if ( ( DG_MODE_CIRC == dgOpMode ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) ) { resMgmtTimer = getMSTimerCount(); currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE; Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rd4850547b287cc1f94ea3617a1902c5278ea86b4 -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision d4850547b287cc1f94ea3617a1902c5278ea86b4) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -734,11 +734,7 @@ if ( ++dialInFlowDataPublicationTimerCounter >= getPublishDialInFlowDataInterval() ) { S32 flowStPt = (S32)getTargetDialInFlowRate(); -#ifndef SHOW_RAW_FLOW_VALUES F32 measFlow = getMeasuredDialInFlowRate(); -#else - F32 measFlow = getFPGADialysateFlow(); -#endif F32 measRotSpd = getMeasuredDialInPumpRotorSpeed(); F32 measSpd = getMeasuredDialInPumpSpeed(); F32 measMCSpd = getMeasuredDialInPumpMCSpeed(); Index: firmware/App/HDCommon.h =================================================================== diff -u -r38e9e1791f490f7a95b7a7040973a6761f7603ff -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 38e9e1791f490f7a95b7a7040973a6761f7603ff) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -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 @@ -44,7 +44,7 @@ #define DISABLE_PUMP_DIRECTION_CHECKS 1 #define DISABLE_PRESSURE_CHECKS 1 // #define SHOW_LOAD_CELL_IN_ROTOR_RPM 1 -// #define SHOW_RAW_FLOW_VALUES 1 +// #define READ_FPGA_ASYNC_DATA 1 #include #include Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r109ee17a1d5a729df23854809051aee23fa95ce7 -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 109ee17a1d5a729df23854809051aee23fa95ce7) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -633,17 +633,8 @@ void signalReservoirsSwitched( void ) { DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); - DG_RESERVOIR_ID_T inactiveRes; + DG_RESERVOIR_ID_T inactiveRes = ( activeRes == DG_RESERVOIR_1 ? DG_RESERVOIR_2 : DG_RESERVOIR_1 ); - // get volume of inactive reservoir - if ( DG_RESERVOIR_2 == activeRes ) - { - inactiveRes = DG_RESERVOIR_1; - } - else - { - inactiveRes = DG_RESERVOIR_2; - } // update UF volume from prior reservoirs per tentative res volume for last reservoir measUFVolumeFromPriorReservoirs += ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); } @@ -676,7 +667,7 @@ resVolume = getLoadCellWeightInGrams( LOAD_CELL_RESERVOIR_2_PRIMARY ); } - // update UF volume from prior reservoirs per final res volume for last reservoir a bit after we've switched + // update UF volume from prior reservoirs per final res volume for last reservoir a bit after we've switched and reservoir has settled measUFVolumeFromPriorReservoirs -= ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); resFinalVolume[ inactiveRes ] = resVolume; measUFVolumeFromPriorReservoirs += ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -41,6 +41,8 @@ FPGA_STATE_RCV_HEADER, ///< Receive header state for the FPGA. FPGA_STATE_WRITE_ALL_ACTUATORS, ///< Write actuators command state for the FPGA. FPGA_STATE_RCV_ALL_SENSORS, ///< Receive sensors state for the FPGA. + FPGA_STATE_READ_ALL_SENSORS2, ///< Read async sensors state for the FPGA. + FPGA_STATE_RCV_ALL_SENSORS2, ///< Receive async sensors state for the FPGA. FPGA_STATE_FAILED, ///< Failed state for the FPGA. NUM_OF_FPGA_STATES ///< Number of FPGA states. } FPGA_STATE_T; @@ -51,6 +53,7 @@ #define FPGA_HEADER_START_ADDR 0x0000 ///< Start address for FPGA header data. #define FPGA_BULK_READ_START_ADDR 0x0100 ///< Start address for FPGA continuous priority reads. #define FPGA_BULK_WRITE_START_ADDR 0x0008 ///< Start address for FPGA continuous priority writes. +#define FPGA_BULK_ASYNC_READ_START_ADDR 0x0200 ///< Start address for FPGA async reads. #define FPGA_WRITE_CMD_BUFFER_LEN (FPGA_PAGE_SIZE+8) ///< FPGA write command buffer byte length. #define FPGA_READ_CMD_BUFFER_LEN 8 ///< FPGA read command buffer byte length. @@ -142,6 +145,30 @@ { U08 bloodValveSetState; ///< Reg 8. Set valve actuator states. } FPGA_ACTUATORS_T; + +/// Record structure for FPGA async (as needed) reads. +typedef struct // TODO - add all sensor readings to this structure per FPGA register map +{ + U16 fpgaDieTemp; ///< Reg 512. Internal FPGA die temperature. + U16 fpgaADCVccVoltage; ///< Reg 514. Internal FPGA Vcc voltage. + U16 fpgaADCVccAuxVoltage; ///< Reg 516. Internal FPGA Vcc aux voltage. + U16 fpgaADCVpvnVoltage; ///< Reg 518. Internal FPGA VPVN voltage. + U16 fpgaVAux0Voltage; ///< Reg 520. Aux. voltage 0. + U16 fpgaVAux1Voltage; ///< Reg 522. Aux. voltage 1. + U16 fpgaVAux2Voltage; ///< Reg 524. Aux. voltage 2. + U16 fpgaVAux3Voltage; ///< Reg 526. Aux. voltage 3. + U16 fpgaVAux8Voltage; ///< Reg 528. Aux. voltage 8. + U16 fpgaVAux9Voltage; ///< Reg 530. Aux. voltage 9. + U16 fpgaVAux10Voltage; ///< Reg 532. Aux. voltage 10. + U16 fpgaVAux11Voltage; ///< Reg 534. Aux. voltage 11. + F32 bloodFlowSoundSpeed; ///< Reg 536. Blood flow sound speed. + F32 bloodFlowAccFlow; ///< Reg 540. Blood flow accumulated flow. + F32 bloodFlowSignalStrength; ///< Reg 544. Blood flow signal strength. + F32 dialysateInFlowSoundSpeed; ///< Reg 548. Dialysate inlet flow sound speed. + F32 dialysateInFlowAccFlow; ///< Reg 552. Dialysate inlet flow accumulated flow. + F32 dialysateInFlowSignalStrength; ///< Reg 556. Dialysate inlet flow signal strength. + U16 fpgaVAux5Voltage; ///< Reg 560. Aux. voltage 5. +} FPGA_SENSORS2_T; #pragma pack(pop) // ********** private data ********** @@ -172,15 +199,20 @@ // FPGA data static FPGA_HEADER_T fpgaHeader; ///< Record of last received FPGA header data. -static FPGA_SENSORS_T fpgaSensorReadings; ///< Record of last received FPGA sensor data. -static FPGA_ACTUATORS_T fpgaActuatorSetPoints; ///< Record of next transmitted FPGA actuator data. +static FPGA_SENSORS_T fpgaSensorReadings; ///< Record of last received FPGA priority sensor data. +static FPGA_ACTUATORS_T fpgaActuatorSetPoints; ///< Record of next transmitted FPGA priority actuator data. +static FPGA_SENSORS2_T fpgaSensorReadings2; ///< Record of last received async (as needed) FPGA sensor data. // ********** private function prototypes ********** static FPGA_STATE_T handleFPGAReadHeaderState( void ); static FPGA_STATE_T handleFPGAReceiveHeaderState( void ); static FPGA_STATE_T handleFPGAWriteAllActuatorsState( void ); static FPGA_STATE_T handleFPGAReceiveAllSensorsState( void ); +#ifdef READ_FPGA_ASYNC_DATA +static FPGA_STATE_T handleFPGAReceiveAllSensors2State( void ); +static FPGA_STATE_T handleFPGAReadAllSensors2State( void ); +#endif static void resetFPGACommFlags( void ); static void setupDMAForWriteCmd( U32 bytes2Transmit ); @@ -400,6 +432,12 @@ fpgaState = handleFPGAReceiveAllSensorsState(); break; +#ifdef READ_FPGA_ASYNC_DATA + case FPGA_STATE_RCV_ALL_SENSORS2: + fpgaState = handleFPGAReceiveAllSensors2State(); + break; +#endif + case FPGA_STATE_FAILED: // do nothing - we'll be stuck here break; @@ -453,6 +491,12 @@ // do nothing - we'll be stuck here break; +#ifdef READ_FPGA_ASYNC_DATA + case FPGA_STATE_READ_ALL_SENSORS2: + fpgaState = handleFPGAReadAllSensors2State(); + break; +#endif + default: if ( fpgaState >= NUM_OF_FPGA_STATES ) { @@ -634,7 +678,11 @@ fpgaCommRetryCount = 0; // capture the read values memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( FPGA_SENSORS_T ) ); +#ifndef READ_FPGA_ASYNC_DATA result = FPGA_STATE_WRITE_ALL_ACTUATORS; +#else + result = FPGA_STATE_READ_ALL_SENSORS2; +#endif } else // bad CRC { @@ -657,8 +705,94 @@ return result; } +#ifdef READ_FPGA_ASYNC_DATA /*********************************************************************//** * @brief + * The handleFPGAReadAllSensors2State function handles the FPGA state where \n + * the read async sensors command is sent to the FPGA. + * @details + * Inputs : none + * Outputs : read async sensors command sent to FPGA + * @return next FPGA state + *************************************************************************/ +static FPGA_STATE_T handleFPGAReadAllSensors2State( void ) +{ + FPGA_STATE_T result = FPGA_STATE_RCV_ALL_SENSORS2; + U16 crc; + + // construct read command to read low priority async registers starting at address 0x200 + fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; + fpgaReadCmdBuffer[ 1 ] = GET_LSB_OF_WORD( FPGA_BULK_ASYNC_READ_START_ADDR ); + fpgaReadCmdBuffer[ 2 ] = GET_MSB_OF_WORD( FPGA_BULK_ASYNC_READ_START_ADDR ); + fpgaReadCmdBuffer[ 3 ] = sizeof(FPGA_SENSORS2_T); + crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); + 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_SENSORS2_T) + FPGA_CRC_LEN ); + setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); + startDMAReceiptOfReadResp(); + startDMAReadCmd(); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleFPGAReceiveAllSensors2State function handles the FPGA state \n + * where the bulk async read response should be ready to parse. + * @details + * Inputs : none + * Outputs : async sensor values updated + * @return next FPGA state + *************************************************************************/ +static FPGA_STATE_T handleFPGAReceiveAllSensors2State( void ) +{ + FPGA_STATE_T result = FPGA_STATE_READ_ALL_SENSORS2; + + // if bulk read command is ACK'd, collect the readings + if ( TRUE == fpgaReadCommandResponseReceived ) + { + // did FPGA Ack the read command? + if ( fpgaReadResponseBuffer[ 0 ] == FPGA_READ_CMD_ACK ) + { + U32 rspSize = FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_SENSORS2_T); + U32 crcPos = rspSize; + U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); + + // does the FPGA response CRC check out? + if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) + { + fpgaCommRetryCount = 0; + // capture the read values + memcpy( &fpgaSensorReadings2, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( FPGA_SENSORS2_T ) ); + result = FPGA_STATE_WRITE_ALL_ACTUATORS; + } + else // bad CRC + { + fpgaCommRetryCount++; + } + } + else // read command was NAK'd + { + fpgaCommRetryCount++; + } + } + else // no response to read command + { + fpgaCommRetryCount++; + } + + // shouldn't be any data received at this time + consumeUnexpectedData(); + + return result; +} +#endif + +/*********************************************************************//** + * @brief * The execFPGATest function executes the FPGA self-test. \n * @details * Inputs : fpgaHeader @@ -871,8 +1005,38 @@ fpgaHeader.fpgaControl = ctrl; } +#ifdef READ_FPGA_ASYNC_DATA /*********************************************************************//** * @brief + * The getFPGABloodFlowSignalStrength function gets the latest blood flow \n + * signal strength reading. + * @details + * Inputs : fpgaSensorReadings2 + * Outputs : none + * @return last blood flow signal strength reading + *************************************************************************/ +F32 getFPGABloodFlowSignalStrength( void ) +{ + return fpgaSensorReadings2.bloodFlowSignalStrength; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowSignalStrength function gets the latest dialysate \n + * flow signal strength reading. + * @details + * Inputs : fpgaSensorReadings2 + * Outputs : none + * @return last dialysate flow signal strength reading + *************************************************************************/ +F32 getFPGADialysateFlowSignalStrength( void ) +{ + return fpgaSensorReadings2.dialysateInFlowSignalStrength; +} +#endif + +/*********************************************************************//** + * @brief * The getFPGABloodFlow function gets the latest blood flow reading. * @details * Inputs : fpgaSensorReadings Index: firmware/App/Services/FPGA.h =================================================================== diff -u -r4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a -r4b22b45e775c0525bc1d76e83e265af91a59785e --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 4ebc1f7e1aeb3a332e91fcdd1bbbe1a01873d93a) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 4b22b45e775c0525bc1d76e83e265af91a59785e) @@ -45,6 +45,11 @@ U16 getFPGAStatus( void ); void setFPGAControl( U16 ctrl ); +#ifdef READ_FPGA_ASYNC_DATA +F32 getFPGABloodFlowSignalStrength( void ); +F32 getFPGADialysateFlowSignalStrength( void ); +#endif + F32 getFPGABloodFlow( void ); F32 getFPGADialysateFlow( void );