Index: App/Services/FPGA.c =================================================================== diff -u -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 -r40a959e1341c8964f872df462ac3a2d874e3b0b3 --- App/Services/FPGA.c (.../FPGA.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) +++ App/Services/FPGA.c (.../FPGA.c) (revision 40a959e1341c8964f872df462ac3a2d874e3b0b3) @@ -16,32 +16,35 @@ * **************************************************************************/ -//#include // for memcpy() +#include // for memset(), memcpy() #include "sci.h" #include "sys_dma.h" #include "CommInterrupts.h" #include "SystemCommMessages.h" +#include "Utilities.h" #include "FPGA.h" // ********** private definitions ********** typedef enum FPGA_States { FPGA_STATE_START = 0, - FPGA_STATE_READ_VERS_AND_DIAG, - FPGA_STATE_RCV_VERS_AND_DIAG, + FPGA_STATE_READ_HEADER, + FPGA_STATE_RCV_HEADER, FPGA_STATE_WRITE_ALL_ACTUATORS, FPGA_STATE_RCV_ALL_SENSORS, FPGA_STATE_FAILED, NUM_OF_FPGA_STATES } FPGA_STATE_T; -#define FPGA_WRITE_CMD_BUFFER_LEN 16 +#define FPGA_PAGE_SIZE 256 + +#define FPGA_WRITE_CMD_BUFFER_LEN (FPGA_PAGE_SIZE+8) #define FPGA_READ_CMD_BUFFER_LEN 8 #define FPGA_WRITE_RSP_BUFFER_LEN 8 -#define FPGA_READ_RSP_BUFFER_LEN 100 +#define FPGA_READ_RSP_BUFFER_LEN (FPGA_PAGE_SIZE+8) #define FPGA_WRITE_CMD_CODE 0x55 #define FPGA_READ_CMD_CODE 0x5A @@ -63,14 +66,52 @@ #pragma pack(push,1) typedef struct { - U08 artBloodValveState; // arterial blood valve state - U08 venBloodValveState; // venous blood valve state + U08 fpgaId; + U08 fpgaRev; + U08 fpgaDiag; + U08 gap1; + U08 fpgaStatusLow; + U08 fpgaStatusHigh; + U08 fpgaControlLow; + U08 fpgaControlHigh; +} FPGA_HEADER_T; + +typedef struct +{ + U08 gap1; + U08 bloodLeakLow; + U08 bloodLeakHigh; + U08 gap2; + U08 gap3; + U08 adc1bLow; + U08 adc1bMid; + U08 adc1bHigh; + U08 adc2bLow; + U08 adc2bMid; + U08 adc2bHigh; + U08 dialysateTemp1Low; + U08 dialysateTemp1Mid; + U08 dialysateTemp1High; + U08 venousPressureLow; + U08 venousPressureMid; + U08 venousPressureHigh; + U08 arterialPressureLow; + U08 arterialPressureMid; + U08 arterialPressureHigh; + U08 gap4; + U08 adc1aLow; + U08 adc1aMid; + U08 adc1aHigh; + U08 adc2aLow; + U08 adc2aMid; + U08 adc2aHigh; + U08 dialysateTemp2Low; + U08 dialysateTemp2Mid; + U08 dialysateTemp2High; } FPGA_SENSORS_T; typedef struct { - U08 artBloodValveState; // arterial blood valve set state - U08 venBloodValveState; // venous blood valve set state } FPGA_ACTUATORS_T; #pragma pack(pop) @@ -81,16 +122,16 @@ static U32 fpgaReceiptCounter = 0; static U32 fpgaTransmitCounter = 0; +static BOOL fpgaWriteCommandInProgress = FALSE; +static BOOL fpgaReadCommandInProgress = FALSE; +static BOOL fpgaBulkWriteAndReadInProgress = FALSE; +static BOOL fpgaWriteCommandACKed = FALSE; +static BOOL fpgaReadCommandACKed = FALSE; -// FPGA received sensor data from DMA bulk read -static FPGA_SENSORS_T fpgaSensorReadings; -// FPGA transmit actuator set points via DMA bulk write -static FPGA_ACTUATORS_T fpgaActuatorSetPoints; - // FPGA comm buffers -static U08 fpgaWriteCmdBuffer[FPGA_WRITE_CMD_BUFFER_LEN];// = {1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0}; -static U08 fpgaReadCmdBuffer[FPGA_READ_CMD_BUFFER_LEN];// = {0,0,0,0,0,0,0,0}; -static U08 fpgaWriteResponseBuffer[FPGA_WRITE_RSP_BUFFER_LEN];// = {0,0,0,0,0,0,0,0}; +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 @@ -100,26 +141,18 @@ static g_dmaCTRL fpgaDMAReadRespControlRecord; // FPGA data +static FPGA_HEADER_T fpgaHeader; +static FPGA_SENSORS_T fpgaSensorReadings; +static FPGA_ACTUATORS_T fpgaActuatorSetPoints; -U08 fpgaId; // FPGA Id -U08 fpgaRev; // FPGA Revision -U08 fpgaDiag; // FPGA diagnostic register - -// sensor readings -DATA_DECL( OPN_CLS_STATE_T, ArtBloodValveState, dataArterialBloodValveState, STATE_CLOSED, STATE_CLOSED ); -DATA_DECL( OPN_CLS_STATE_T, VenBloodValveState, dataVenousBloodValveState, STATE_CLOSED, STATE_CLOSED ); - -// actuator set points -DATA_DECL( OPN_CLS_STATE_T, ArtBloodValveSetState, dataArterialBloodValveSetState, STATE_CLOSED, STATE_CLOSED ); -DATA_DECL( OPN_CLS_STATE_T, VenBloodValveSetState, dataVenousBloodValveSetState, STATE_CLOSED, STATE_CLOSED ); - // ********** private function prototypes ********** -static FPGA_STATE_T handleFPGAReadVersionAndDiagnosticState( void ); -static FPGA_STATE_T handleFPGAReceiveVersionAndDiagnosticState( void ); +static FPGA_STATE_T handleFPGAReadHeaderState( void ); +static FPGA_STATE_T handleFPGAReceiveHeaderState( void ); static FPGA_STATE_T handleFPGAWriteAllActuatorsState( void ); static FPGA_STATE_T handleFPGAReceiveAllSensorsState( void ); +static void resetFPGACommFlags( void ); static void setupDMAForWriteCmd( U32 bytes2Transmit ); static void startDMAWriteCmd( void ); static void setupDMAForWriteResp( U32 bytes2Receive ); @@ -140,6 +173,11 @@ *************************************************************************/ void initFPGA( void ) { + // initialize fpga data structures + memset( &fpgaHeader, 0, sizeof(FPGA_HEADER_T) ); + memset( &fpgaSensorReadings, 0, sizeof(FPGA_SENSORS_T) ); + memset( &fpgaActuatorSetPoints, 0, sizeof(FPGA_ACTUATORS_T) ); + // enable interrupt notifications for FPGA serial port sciEnableNotification( scilinREG, SCI_OE_INT | SCI_FE_INT ); @@ -233,6 +271,27 @@ } /************************************************************************* + * @brief resetFPGACommFlags + * The resetFPGACommFlags function resets the various fpga comm flags and \n + * counters. + * @details + * Inputs : none + * Outputs : fpga comm flags & counters reset + * @param none + * @return none + *************************************************************************/ +static void resetFPGACommFlags( void ) +{ + fpgaWriteCommandACKed = FALSE; + fpgaReadCommandACKed = FALSE; + fpgaWriteCommandInProgress = FALSE; + fpgaReadCommandInProgress = FALSE; + fpgaBulkWriteAndReadInProgress = FALSE; + fpgaTransmitCounter = 0; + fpgaReceiptCounter = 0; +} + +/************************************************************************* * @brief signalFPGAReceiptCompleted * The signalFPGAReceiptCompleted function increments a counter to indicate \n * that another DMA receipt from the FPGA has completed. @@ -245,6 +304,28 @@ void signalFPGAReceiptCompleted( void ) { fpgaReceiptCounter++; + // did FPGA Ack last command? + if ( TRUE == fpgaWriteCommandInProgress ) + { + fpgaWriteCommandInProgress = FALSE; + fpgaWriteCommandACKed = ( fpgaWriteResponseBuffer[0] == FPGA_WRITE_CMD_ACK ? TRUE : FALSE ); + } + else if ( TRUE == fpgaReadCommandInProgress ) + { + fpgaReadCommandInProgress = FALSE; + fpgaReadCommandACKed = ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ? TRUE : FALSE ); + } + // first receipt? + if ( 1 == fpgaReceiptCounter ) + { + // see if we want to follow up with a bulk read command + if ( TRUE == fpgaBulkWriteAndReadInProgress ) + { + fpgaBulkWriteAndReadInProgress = FALSE; + fpgaReadCommandInProgress = TRUE; + // TODO - initiate bulk read command + } + } } /************************************************************************* @@ -263,33 +344,30 @@ } /************************************************************************* - * @brief execFPGA - * The execFPGA function manages data exchanges with the FPGA. + * @brief execFPGAIn + * The execFPGA function manages incoming data exchanges with the FPGA. * @details - * Inputs : none - * Outputs : none + * Inputs : fpgaState + * Outputs : fpgaState * @param none * @return none *************************************************************************/ -void execFPGA( void ) +void execFPGAIn( void ) { + resetFPGACommFlags(); + + // FPGA incoming state machine switch ( fpgaState ) { case FPGA_STATE_START: - fpgaState = FPGA_STATE_READ_VERS_AND_DIAG; + fpgaState = FPGA_STATE_READ_HEADER; break; - case FPGA_STATE_READ_VERS_AND_DIAG: - fpgaState = handleFPGAReadVersionAndDiagnosticState(); + case FPGA_STATE_RCV_HEADER: + fpgaState = handleFPGAReceiveHeaderState(); break; - case FPGA_STATE_RCV_VERS_AND_DIAG: - fpgaState = handleFPGAReceiveVersionAndDiagnosticState(); - break; - case FPGA_STATE_WRITE_ALL_ACTUATORS: - fpgaState = handleFPGAWriteAllActuatorsState(); - break; case FPGA_STATE_RCV_ALL_SENSORS: fpgaState = handleFPGAReceiveAllSensorsState(); @@ -300,34 +378,86 @@ break; default: - // TODO - fault + if ( fpgaState >= NUM_OF_FPGA_STATES ) + { + // TODO - s/w fault + } + else + { + // ok, some states handled in the outgoing state machine + } break; } } /************************************************************************* - * @brief handleFPGAReadVersionAndDiagnosticState - * The handleFPGAReadVersionAndDiagnosticState function handles the FPGA state \n - * where the read version/diag command is sent to the FPGA. + * @brief execFPGAOut + * The execFPGAOut function manages outgoing data exchanges with the FPGA. * @details + * Inputs : fpgaState + * Outputs : fpgaState + * @param none + * @return none + *************************************************************************/ +void execFPGAOut( void ) +{ + resetFPGACommFlags(); + + // FPGA outgoing state machine + switch ( fpgaState ) + { + case FPGA_STATE_READ_HEADER: + fpgaState = handleFPGAReadHeaderState(); + break; + + + + case FPGA_STATE_WRITE_ALL_ACTUATORS: + fpgaState = handleFPGAWriteAllActuatorsState(); + break; + + case FPGA_STATE_FAILED: + // do nothing - we'll be stuck here + break; + + default: + if ( fpgaState >= NUM_OF_FPGA_STATES ) + { + // TODO - s/w fault + } + else + { + // ok, some states handled in the incoming state machine + } + break; + } +} + +/************************************************************************* + * @brief handleFPGAReadHeaderState + * The handleFPGAReadHeaderState function handles the FPGA state where \n + * the read header registers command is sent to the FPGA. + * @details * Inputs : none * Outputs : read command sent to FPGA * @param none * @return next FPGA state *************************************************************************/ -static FPGA_STATE_T handleFPGAReadVersionAndDiagnosticState( void ) +static FPGA_STATE_T handleFPGAReadHeaderState( void ) { - FPGA_STATE_T result = FPGA_STATE_RCV_VERS_AND_DIAG; + FPGA_STATE_T result = FPGA_STATE_RCV_HEADER; + 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] = 0x03; // read 3 registers - fpgaReadCmdBuffer[4] = 0x00; // no CRC for now - fpgaReadCmdBuffer[5] = 0x00; // TODO - add a 16-bit CRC function to calculate CRC + 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 ); // prep DMA for sending the read cmd and receiving the response - setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + 3 + FPGA_CRC_LEN ); + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_HEADER_T) + FPGA_CRC_LEN ); setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); startDMAReceiptOfReadResp(); startDMAReadCmd(); @@ -336,33 +466,29 @@ } /************************************************************************* - * @brief handleFPGAReceiveVersionAndDiagnosticState - * The handleFPGAReceiveVersionAndDiagnosticState function handles the FPGA state \n - * where the version/diag read response should be ready to parse. + * @brief handleFPGAReceiveHeaderState + * The handleFPGAReceiveHeaderState function handles the FPGA state \n + * where the header registers read response should be ready to take in. * @details * Inputs : none - * Outputs : version/diag values updated + * Outputs : header register values updated * @param none * @return next FPGA state *************************************************************************/ -static FPGA_STATE_T handleFPGAReceiveVersionAndDiagnosticState( void ) +static FPGA_STATE_T handleFPGAReceiveHeaderState( void ) { - FPGA_STATE_T result = FPGA_STATE_READ_VERS_AND_DIAG; + FPGA_STATE_T result = FPGA_STATE_READ_HEADER; - // did FPGA response? + // did we get an FPGA response? if ( fpgaReceiptCounter > 0 ) { - fpgaReceiptCounter = 0; - fpgaTransmitCounter = 0; // did FPGA Ack the read command? if ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ) { // does the FPGA response CRC check out? if ( 1 ) // TODO - check response CRC { // capture the read values - fpgaId = fpgaReadResponseBuffer[1]; - fpgaRev = fpgaReadResponseBuffer[2]; - fpgaDiag = fpgaReadResponseBuffer[3]; + memcpy( &fpgaHeader, fpgaReadResponseBuffer, sizeof(FPGA_HEADER_T) ); result = FPGA_STATE_WRITE_ALL_ACTUATORS; } } @@ -385,6 +511,11 @@ { FPGA_STATE_T result = FPGA_STATE_RCV_ALL_SENSORS; + fpgaWriteCommandInProgress = TRUE; + fpgaBulkWriteAndReadInProgress = TRUE; + // TODO - setup for bulk write and follow-up bulk read commands + // TODO - initiate bulk write command + return result; } @@ -402,6 +533,18 @@ { FPGA_STATE_T result = FPGA_STATE_WRITE_ALL_ACTUATORS; + // check commands success + if ( FALSE == fpgaWriteCommandACKed ) + { + // TODO - ??? + } + if ( FALSE == fpgaReadCommandACKed ) + { + // TODO - ??? + } + + // TODO - collect sensor readings + return result; } @@ -538,151 +681,76 @@ * The getFPGAId function gets the version read from the Id register \n * of the FPGA. * @details - * Inputs : fpgaId + * Inputs : fpgaHeader * Outputs : none * @param none * @return Id *************************************************************************/ U08 getFPGAId( void ) { - return fpgaId; + return fpgaHeader.fpgaId; } /************************************************************************* * @brief getFPGARev * The getFPGARev function gets the revision read from the Rev register \n * of the FPGA. * @details - * Inputs : fpgaRev + * Inputs : fpgaHeader * Outputs : none * @param none * @return Revision *************************************************************************/ U08 getFPGARev( void ) { - return fpgaRev; + return fpgaHeader.fpgaRev; } /************************************************************************* * @brief getFPGADiag * The getFPGADiag function gets the version read from the diagnostic register \n * of the FPGA. * @details - * Inputs : fpgaDiag + * Inputs : fpgaHeader * Outputs : none * @param none * @return fpgaDiag *************************************************************************/ U08 getFPGADiag( void ) { - return fpgaDiag; + return fpgaHeader.fpgaDiag; } /************************************************************************* - * @brief getArterialBloodValveState - * The getArterialBloodValveState function gets the latest arterial blood \n - * valve state read from the FPGA. + * @brief getFPGAStatus + * The getFPGAStatus function gets the version read from the diagnostic register \n + * of the FPGA. * @details - * Inputs : dataArterialBloodValveState + * Inputs : fpgaHeader * Outputs : none * @param none - * @return The last read state for the arterial blood valve + * @return fpgaDiag *************************************************************************/ -DATA_GET( OPN_CLS_STATE_T, getArterialBloodValveState, dataArterialBloodValveState ) +U16 getFPGAStatus( void ) +{ + U16 result = MAKE_WORD_OF_BYTES(fpgaHeader.fpgaStatusHigh,fpgaHeader.fpgaStatusLow); -/************************************************************************* - * @brief getArterialBloodValveSetState - * The getArterialBloodValveSetState function gets the current arterial blood \n - * valve set state that is being sent to the FPGA. - * @details - * Inputs : dataArterialBloodValveSetState - * Outputs : none - * @param none - * @return The current set state for the arterial blood valve - *************************************************************************/ -DATA_GET( OPN_CLS_STATE_T, getArterialBloodValveSetState, dataArterialBloodValveSetState ) + return result; +} /************************************************************************* - * @brief getVenousBloodValveState - * The getVenousBloodValveState function gets the latest venous blood \n - * valve state read from the FPGA. + * @brief getFPGADiag + * The getFPGADiag function gets the version read from the diagnostic register \n + * of the FPGA. * @details - * Inputs : dataVenousBloodValveState + * Inputs : fpgaHeader * Outputs : none * @param none - * @return The last read state for the venous blood valve + * @return fpgaDiag *************************************************************************/ -DATA_GET( OPN_CLS_STATE_T, getVenousBloodValveState, dataVenousBloodValveState ) +void setFPGAControl( U16 ctrl ) +{ + fpgaHeader.fpgaControlHigh = GET_MSB_OF_WORD( ctrl ); + fpgaHeader.fpgaControlLow = GET_MSB_OF_WORD( ctrl ); +} -/************************************************************************* - * @brief getVenousBloodValveSetState - * The getVenousBloodValveSetState function gets the current venous blood \n - * valve set state that is being sent to the FPGA. - * @details - * Inputs : dataVenousBloodValveSetState - * Outputs : none - * @param none - * @return The current set state for the venous blood valve - *************************************************************************/ -DATA_GET( OPN_CLS_STATE_T, getVenousBloodValveSetState, dataVenousBloodValveSetState ) - - - - -/************************************************************************* - * @brief testSetArterialBloodValveStateOverride and testResetArterialBloodValveStateOverride - * The testSetArterialBloodValveStateOverride function overrides the \n - * arterial blood valve state that is being read from the FPGA. \n - * The testResetArterialBloodValveStateOverride function resets a previous \n - * override of the arterial blood valve state back to sensed state. \n - * @details - * Inputs : none - * Outputs : dataArterialBloodValveState - * @param none - * @return TRUE if successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( OPN_CLS_STATE_T, testSetArterialBloodValveStateOverride, testResetArterialBloodValveStateOverride, dataArterialBloodValveState ) - -/************************************************************************* - * @brief testSetArterialBloodValveSetStateOverride and testResetArterialBloodValveSetStateOverride - * The testSetArterialBloodValveSetStateOverride function overrides the \n - * arterial blood valve set state that is being sent to the FPGA. \n - * The testResetArterialBloodValveSetStateOverride function resets a previous \n - * override of the arterial blood valve set state back to controlled state. - * @details - * Inputs : none - * Outputs : dataArterialBloodValveSetState - * @param none - * @return TRUE if successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( OPN_CLS_STATE_T, testSetArterialBloodValveSetStateOverride, testResetArterialBloodValveSetStateOverride, dataArterialBloodValveSetState ) - -/************************************************************************* - * @brief testSetVenousBloodValveStateOverride and testResetVenousBloodValveStateOverride - * The testSetVenousBloodValveStateOverride function overrides the \n - * venous blood valve state that is being read from the FPGA. \n - * The testResetVenousBloodValveStateOverride function resets a previous \n - * override of the venous blood valve state back to sensed state. - * @details - * Inputs : none - * Outputs : dataVenousBloodValveState - * @param none - * @return TRUE if successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( OPN_CLS_STATE_T, testSetVenousBloodValveStateOverride, testResetVenousBloodValveStateOverride, dataVenousBloodValveState ) - -/************************************************************************* - * @brief testSetVenousBloodValveSetStateOverride and testResetVenousBloodValveSetStateOverride - * The testSetVenousBloodValveSetStateOverride function overrides the \n - * venous blood valve state that is being read from the FPGA. \n - * The testResetVenousBloodValveSetStateOverride function resets a previous \n - * override of the venous blood valve set state back to controlled state. \n - * @details - * Inputs : none - * Outputs : dataVenousBloodValveSetState - * @param none - * @return TRUE if successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( OPN_CLS_STATE_T, testSetVenousBloodValveSetStateOverride, testResetVenousBloodValveSetStateOverride, dataVenousBloodValveSetState ) - -