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