Index: App/Services/FPGA.c =================================================================== diff -u -r81ca79980a75ab71985d3d610bcef45fd6730458 -rc8c2c1b2a5b2d4836d19fa3c719446c3089c4a36 --- App/Services/FPGA.c (.../FPGA.c) (revision 81ca79980a75ab71985d3d610bcef45fd6730458) +++ App/Services/FPGA.c (.../FPGA.c) (revision c8c2c1b2a5b2d4836d19fa3c719446c3089c4a36) @@ -21,10 +21,10 @@ #include "sci.h" #include "sys_dma.h" -#include "CommInterrupts.h" +#include "FPGA.h" +#include "Comm.h" #include "SystemCommMessages.h" #include "Utilities.h" -#include "FPGA.h" // ********** private definitions ********** @@ -40,6 +40,7 @@ } FPGA_STATE_T; #define FPGA_PAGE_SIZE 256 +#define FPGA_EXPECTED_ID 0x59 #define FPGA_WRITE_CMD_BUFFER_LEN (FPGA_PAGE_SIZE+8) #define FPGA_READ_CMD_BUFFER_LEN 8 @@ -62,6 +63,8 @@ #define SCI2_RECEIVE_DMA_REQUEST 28 #define SCI2_TRANSMIT_DMA_REQUEST 29 +#define MAX_COMM_ERROR_RETRIES 5 + // FPGA Sensors Record #pragma pack(push,1) typedef struct @@ -70,44 +73,21 @@ U08 fpgaRev; U08 fpgaDiag; U08 gap1; - U08 fpgaStatusLow; - U08 fpgaStatusHigh; - U08 fpgaControlLow; - U08 fpgaControlHigh; + U16 fpgaStatus; + U16 fpgaControl; } 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; + U16 bloodLeak; + U32 adc1b; + U32 adc2b; + U32 dialysateTemp1; + U32 venousPressure; + U32 arterialPressure; + U32 adc1a; + U32 adc2a; + U32 dialysateTemp2; } FPGA_SENSORS_T; typedef struct @@ -120,13 +100,14 @@ // FPGA state static FPGA_STATE_T fpgaState = FPGA_STATE_START; +static U32 fpgaCommRetryCount = 0; 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; +static BOOL fpgaWriteCommandResponseReceived = FALSE; +static BOOL fpgaReadCommandResponseReceived = FALSE; // FPGA comm buffers static U08 fpgaWriteCmdBuffer[FPGA_WRITE_CMD_BUFFER_LEN]; @@ -162,6 +143,8 @@ static void setupDMAForReadResp( U32 bytes2Receive ); static void startDMAReceiptOfReadResp( void ); +static void consumeUnexpectedData( void ); + /************************************************************************* * @brief initFPGA * The initFPGA function initializes the FPGA module. @@ -178,6 +161,12 @@ memset( &fpgaSensorReadings, 0, sizeof(FPGA_SENSORS_T) ); memset( &fpgaActuatorSetPoints, 0, sizeof(FPGA_ACTUATORS_T) ); + // initialize fpga comm buffers + memset( &fpgaWriteCmdBuffer, 0, FPGA_WRITE_CMD_BUFFER_LEN ); + memset( &fpgaReadCmdBuffer, 0, FPGA_READ_CMD_BUFFER_LEN ); + memset( &fpgaWriteResponseBuffer, 0, FPGA_WRITE_RSP_BUFFER_LEN ); + memset( &fpgaReadResponseBuffer, 0, FPGA_READ_RSP_BUFFER_LEN ); + // enable interrupt notifications for FPGA serial port sciEnableNotification( scilinREG, SCI_OE_INT | SCI_FE_INT ); @@ -263,11 +252,8 @@ fpgaDMAReadRespControlRecord.FRDOFFSET = 0; // not used fpgaDMAReadRespControlRecord.FRSOFFSET = 0; // not used - // TODO - this is a DMA xmit and recv via loopback test -// setupDMAForWriteResp( 8 ); -// setupDMAForWriteCmd( 8 ); -// startDMAReceiptOfWriteResp(); -// startDMAWriteCmd(); + // there shouldn't be any data pending yet + consumeUnexpectedData(); } /************************************************************************* @@ -282,8 +268,8 @@ *************************************************************************/ static void resetFPGACommFlags( void ) { - fpgaWriteCommandACKed = FALSE; - fpgaReadCommandACKed = FALSE; + fpgaWriteCommandResponseReceived = FALSE; + fpgaReadCommandResponseReceived = FALSE; fpgaWriteCommandInProgress = FALSE; fpgaReadCommandInProgress = FALSE; fpgaBulkWriteAndReadInProgress = FALSE; @@ -308,23 +294,22 @@ if ( TRUE == fpgaWriteCommandInProgress ) { fpgaWriteCommandInProgress = FALSE; - fpgaWriteCommandACKed = ( fpgaWriteResponseBuffer[0] == FPGA_WRITE_CMD_ACK ? TRUE : FALSE ); + fpgaWriteCommandResponseReceived = TRUE; } else if ( TRUE == fpgaReadCommandInProgress ) { fpgaReadCommandInProgress = FALSE; - fpgaReadCommandACKed = ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ? TRUE : FALSE ); + fpgaReadCommandResponseReceived = TRUE; } - // first receipt? - if ( 1 == fpgaReceiptCounter ) + + // see if we want to follow up with a bulk read command + if ( TRUE == fpgaBulkWriteAndReadInProgress ) { - // see if we want to follow up with a bulk read command - if ( TRUE == fpgaBulkWriteAndReadInProgress ) - { - fpgaBulkWriteAndReadInProgress = FALSE; - fpgaReadCommandInProgress = TRUE; - // TODO - initiate bulk read command - } + fpgaBulkWriteAndReadInProgress = FALSE; + fpgaReadCommandInProgress = TRUE; + // initiate bulk read command + startDMAReceiptOfReadResp(); + startDMAReadCmd(); } } @@ -354,8 +339,6 @@ *************************************************************************/ void execFPGAIn( void ) { - resetFPGACommFlags(); - // FPGA incoming state machine switch ( fpgaState ) { @@ -367,8 +350,8 @@ fpgaState = handleFPGAReceiveHeaderState(); break; + // TODO - sensor/ADC init/configuration states - case FPGA_STATE_RCV_ALL_SENSORS: fpgaState = handleFPGAReceiveAllSensorsState(); break; @@ -388,6 +371,15 @@ } break; } + + // if retries for commands exceeds limit, fault + if ( fpgaCommRetryCount > MAX_COMM_ERROR_RETRIES ) + { + // TODO - FPGA comm fault + } + + // reset comm flags after processing incoming responses + resetFPGACommFlags(); } /************************************************************************* @@ -401,17 +393,15 @@ *************************************************************************/ void execFPGAOut( void ) { - resetFPGACommFlags(); - // FPGA outgoing state machine switch ( fpgaState ) { case FPGA_STATE_READ_HEADER: fpgaState = handleFPGAReadHeaderState(); break; + // TODO - sensor/ADC init/configuration states - case FPGA_STATE_WRITE_ALL_ACTUATORS: fpgaState = handleFPGAWriteAllActuatorsState(); break; @@ -457,6 +447,7 @@ 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 + fpgaReadCommandInProgress = TRUE; setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof(FPGA_HEADER_T) + FPGA_CRC_LEN ); setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); startDMAReceiptOfReadResp(); @@ -480,20 +471,37 @@ FPGA_STATE_T result = FPGA_STATE_READ_HEADER; // did we get an FPGA response? - if ( ( TRUE == fpgaWriteCommandACKed ) && ( TRUE == fpgaReadCommandACKed ) ) + if ( TRUE == fpgaReadCommandResponseReceived ) { // 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 - memcpy( &fpgaHeader, fpgaReadResponseBuffer, sizeof(FPGA_HEADER_T) ); + { + fpgaCommRetryCount = 0; + // capture the read values + memcpy( &fpgaHeader, &fpgaReadResponseBuffer[1], sizeof(FPGA_HEADER_T) ); result = FPGA_STATE_WRITE_ALL_ACTUATORS; } + else + { + fpgaCommRetryCount++; + } } + else // header read was NAK'd + { + fpgaCommRetryCount++; + } } + else // no response to read command + { + fpgaCommRetryCount++; + } + // shouldn't be any data received at this time + consumeUnexpectedData(); + return result; } @@ -514,7 +522,7 @@ // 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] = 0x02; // start at FPGA address 8 + 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) ); @@ -561,39 +569,69 @@ FPGA_STATE_T result = FPGA_STATE_WRITE_ALL_ACTUATORS; // check bulk write command success - if ( FALSE == fpgaWriteCommandACKed ) + if ( ( FALSE == fpgaWriteCommandResponseReceived ) || ( fpgaWriteResponseBuffer[0] != FPGA_WRITE_CMD_ACK ) ) { // TODO - ??? } // if bulk read command is ACK'd, collect the readings - if ( TRUE == fpgaReadCommandACKed ) + if ( TRUE == fpgaReadCommandResponseReceived ) { - // did we get an FPGA response? - if ( ( TRUE == fpgaWriteCommandACKed ) && ( TRUE == fpgaReadCommandACKed ) ) + // did FPGA Ack the read command? + if ( fpgaReadResponseBuffer[0] == FPGA_READ_CMD_ACK ) { - // 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 { - // does the FPGA response CRC check out? - if ( 1 ) // TODO - check response CRC - { // capture the read values - memcpy( &fpgaSensorReadings, fpgaReadResponseBuffer, sizeof(FPGA_SENSORS_T) ); - result = FPGA_STATE_WRITE_ALL_ACTUATORS; - } + fpgaCommRetryCount = 0; + // capture the read values + memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[1], sizeof(FPGA_SENSORS_T) ); + result = FPGA_STATE_WRITE_ALL_ACTUATORS; } + else // bad CRC + { + fpgaCommRetryCount++; + } } + else // read command was NAK'd + { + fpgaCommRetryCount++; + } } - else + else // no response to read command { - // TODO - ??? + fpgaCommRetryCount++; } + // shouldn't be any data received at this time + consumeUnexpectedData(); return result; } /************************************************************************* + * @brief execFPGATest + * The execFPGATest function executes the FPGA self-test. \n + * @details + * Inputs : fpgaHeader + * Outputs : none + * @param none + * @return passed, or failed + *************************************************************************/ +SELF_TEST_STATUS_T execFPGATest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; + + // check FPGA reported correct ID + if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) + { + result = SELF_TEST_STATUS_PASSED; + } + + return result; +} + +/************************************************************************* * @brief setupDMAForWriteCmd * The setupDMAForWriteCmd function sets the byte count for the next DMA \n * write command to the FPGA. @@ -605,7 +643,15 @@ *************************************************************************/ static void setupDMAForWriteCmd( U32 bytes2Transmit ) { - fpgaDMAWriteControlRecord.FRCNT = bytes2Transmit; + // verify # of bytes does not exceed buffer length + if ( bytes2Transmit <= FPGA_WRITE_CMD_BUFFER_LEN ) + { + fpgaDMAWriteControlRecord.FRCNT = bytes2Transmit; + } + else + { + // TODO - s/w fault + } } /************************************************************************* @@ -637,7 +683,15 @@ *************************************************************************/ static void setupDMAForWriteResp( U32 bytes2Receive ) { - fpgaDMAWriteRespControlRecord.FRCNT = bytes2Receive; + // verify # of bytes does not exceed buffer length + if ( bytes2Receive <= FPGA_WRITE_RSP_BUFFER_LEN ) + { + fpgaDMAWriteRespControlRecord.FRCNT = bytes2Receive; + } + else + { + // TODO - s/w fault + } } /************************************************************************* @@ -669,7 +723,15 @@ *************************************************************************/ static void setupDMAForReadCmd( U32 bytes2Transmit ) { - fpgaDMAReadControlRecord.FRCNT = bytes2Transmit; + // verify # of bytes does not exceed buffer length + if ( bytes2Transmit <= FPGA_READ_CMD_BUFFER_LEN ) + { + fpgaDMAReadControlRecord.FRCNT = bytes2Transmit; + } + else + { + // TODO - s/w fault + } } /************************************************************************* @@ -701,7 +763,15 @@ *************************************************************************/ static void setupDMAForReadResp( U32 bytes2Receive ) { - fpgaDMAReadRespControlRecord.FRCNT = bytes2Receive; + // verify # of bytes does not exceed buffer length + if ( bytes2Receive <= FPGA_READ_RSP_BUFFER_LEN ) + { + fpgaDMAReadRespControlRecord.FRCNT = bytes2Receive; + } + else + { + // TODO - s/w fault + } } /************************************************************************* @@ -778,9 +848,7 @@ *************************************************************************/ U16 getFPGAStatus( void ) { - U16 result = MAKE_WORD_OF_BYTES(fpgaHeader.fpgaStatusHigh,fpgaHeader.fpgaStatusLow); - - return result; + return fpgaHeader.fpgaStatus; } /************************************************************************* @@ -795,7 +863,27 @@ *************************************************************************/ void setFPGAControl( U16 ctrl ) { - fpgaHeader.fpgaControlHigh = GET_MSB_OF_WORD( ctrl ); - fpgaHeader.fpgaControlLow = GET_MSB_OF_WORD( ctrl ); + fpgaHeader.fpgaControl = ctrl; } +/************************************************************************* + * @brief consumeUnexpectedData + * The consumeUnexpectedData function checks to see if a byte is sitting in \n + * the SCI2 received data register. + * @details + * Inputs : fpgaHeader + * Outputs : none + * @param none + * @return fpgaDiag + *************************************************************************/ +static void consumeUnexpectedData( void ) +{ + // clear any errors + sciRxError( scilinREG ); + // if a byte is pending read, read it + if ( 0 != sciIsRxReady( scilinREG ) ) + { + sciReceiveByte( scilinREG ); + } +} +