Index: App/Common.h =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Common.h (.../Common.h) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ App/Common.h (.../Common.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -59,8 +59,8 @@ { STATE_CLOSED = 0, STATE_OPEN, - NUM_OF_TWO_WAY_STATES -} TWO_WAY_STATE_T; + NUM_OF_OPN_CLS_STATES +} OPN_CLS_STATE_T; // **** Common Definitions **** @@ -113,6 +113,35 @@ return result; \ } +// DATA_OVERRIDE_FUNC - creates an override and a reset override function for a DATA +// t = data's type +// o_name = name for override function +// r_name = name for reset override function +// d_name = name of data's variable +#define DATA_OVERRIDE_FUNC( t, o_name, r_name, d_name ) \ +BOOL o_name( t value ) \ +{ \ + BOOL result = FALSE; \ + if ( TRUE == isTestingActivated() ) \ + { \ + result = TRUE; \ + d_name.ovData = value; \ + d_name.override = OVERRIDE_KEY; \ + } \ + return result; \ +} \ +BOOL r_name( void ) \ +{ \ + BOOL result = FALSE; \ + if ( TRUE == isTestingActivated() ) \ + { \ + result = TRUE; \ + d_name.override = OVERRIDE_RESET; \ + d_name.ovData = d_name.ovInitData; \ + } \ + return result; \ +} + // **** VectorCAST Definitions **** #ifdef _VECTORCAST_ Index: App/Controllers/Buttons.c =================================================================== diff -u -r3323966fe741edbb36dffc78317ccf06ed93a68e -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Controllers/Buttons.c (.../Buttons.c) (revision 3323966fe741edbb36dffc78317ccf06ed93a68e) +++ App/Controllers/Buttons.c (.../Buttons.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -24,13 +24,6 @@ // ********** private definitions ********** -typedef enum Button_States -{ - BUTTON_STATE_RELEASED = 0, - BUTTON_STATE_PRESSED, - NUM_OF_BUTTON_STATES -} BUTTON_STATE_T; - typedef enum Button_Self_Test_States { BUTTON_SELF_TEST_STATE_START = 0, @@ -49,11 +42,13 @@ // ********** private data ********** -static BUTTON_STATE_T offButtonState = BUTTON_STATE_RELEASED; +DATA_DECL( BUTTON_STATE_T, OffButtonState, dataOffButtonState, BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED ); +//static BUTTON_STATE_T offButtonState = BUTTON_STATE_RELEASED; static BUTTON_STATE_T prevOffButtonState = BUTTON_STATE_RELEASED; static BOOL offButtonPressPending = FALSE; -static BUTTON_STATE_T stopButtonState = BUTTON_STATE_RELEASED; +DATA_DECL( BUTTON_STATE_T, StopButtonState, dataStopButtonState, BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED ); +//static BUTTON_STATE_T stopButtonState = BUTTON_STATE_RELEASED; static BUTTON_STATE_T prevStopButtonState = BUTTON_STATE_RELEASED; static BOOL stopButtonPressPending = FALSE; static U32 stopButtonPendingTimer = 0; @@ -81,11 +76,11 @@ *************************************************************************/ void initButtons( void ) { - offButtonState = BUTTON_STATE_RELEASED; + //offButtonState = BUTTON_STATE_RELEASED; prevOffButtonState = BUTTON_STATE_RELEASED; offButtonPressPending = FALSE; - stopButtonState = BUTTON_STATE_RELEASED; + //stopButtonState = BUTTON_STATE_RELEASED; prevStopButtonState = BUTTON_STATE_RELEASED; stopButtonPressPending = FALSE; stopButtonPendingTimer = 0; @@ -112,8 +107,8 @@ PIN_SIGNAL_STATE_T stop = getCPLDStopButton(); // set current button states read from CPLD - offButtonState = ( off == PIN_SIGNAL_HIGH ? BUTTON_STATE_PRESSED : BUTTON_STATE_RELEASED ); - stopButtonState = ( stop == PIN_SIGNAL_HIGH ? BUTTON_STATE_PRESSED : BUTTON_STATE_RELEASED ); + dataOffButtonState.data = ( off == PIN_SIGNAL_HIGH ? BUTTON_STATE_PRESSED : BUTTON_STATE_RELEASED ); + dataStopButtonState.data = ( stop == PIN_SIGNAL_HIGH ? BUTTON_STATE_PRESSED : BUTTON_STATE_RELEASED ); // handle button state transitions for stop button handleStopButtonProcessing(); @@ -143,41 +138,29 @@ } /************************************************************************* - * @brief isButtonPressedRaw - * The isButtonPressedRaw function determines whether a given button is currently \n - * pressed. + * @brief getOffButtonState + * The getOffButtonState function determines whether the off button is \n + * currently pressed. * @details - * Inputs : offButtonState, prevOffButtonState, stopButtonState, prevStopButtonState + * Inputs : dataOffButtonState, prevOffButtonState * Outputs : none - * @param button - * @return true if given button is pressed, false if not + * @param none + * @return BUTTON_STATE_PRESSED if off button pressed, BUTTON_STATE_RELEASED if not *************************************************************************/ -BOOL isButtonPressedRaw( BUTTON_T button ) -{ - BOOL result = FALSE; +DATA_GET( BUTTON_STATE_T, getOffButtonState, dataOffButtonState ) - switch ( button ) - { - case BUTTON_OFF: - if ( offButtonState == BUTTON_STATE_PRESSED ) - { - result = TRUE; - } - break; - case BUTTON_STOP: - if ( stopButtonState == BUTTON_STATE_PRESSED ) - { - result = TRUE; - } - break; - default: - // TODO - s/w fault - break; - } +/************************************************************************* + * @brief getStopButtonState + * The getStopButtonState function determines whether the stop button is \n + * currently pressed. + * @details + * Inputs : dataStopButtonState, prevStopButtonState + * Outputs : none + * @param none + * @return BUTTON_STATE_PRESSED if stop button pressed, BUTTON_STATE_RELEASED if not + *************************************************************************/ +DATA_GET( BUTTON_STATE_T, getStopButtonState, dataStopButtonState ) - return result; -} - /************************************************************************* * @brief userConfirmOffButton * The userConfirmOffButton function handles user confirmation of the off \n @@ -230,7 +213,7 @@ // no break here so we pass through directly to in progress processing case BUTTON_SELF_TEST_STATE_IN_PROGRESS: - if ( ( offButtonState == BUTTON_STATE_RELEASED ) && ( stopButtonState == BUTTON_STATE_RELEASED ) ) + if ( ( dataOffButtonState.data == BUTTON_STATE_RELEASED ) && ( dataStopButtonState.data == BUTTON_STATE_RELEASED ) ) { result = SELF_TEST_STATUS_PASSED; buttonSelfTestState = BUTTON_SELF_TEST_STATE_COMPLETE; @@ -266,7 +249,7 @@ * Inputs : Current operation mode. * Outputs : none * @param none - * @return true if can turn system off in current mode, false if not + * @return TRUE if can turn system off in current mode, FALSE if not *************************************************************************/ static BOOL isCurrentOpModeOkToTurnOff( void ) { @@ -294,9 +277,9 @@ static void handleOffButtonProcessing( void ) { // handle button state transitions for off button - if ( offButtonState != prevOffButtonState ) + if ( getOffButtonState() != prevOffButtonState ) { - if ( offButtonState == BUTTON_STATE_PRESSED ) + if ( getOffButtonState() == BUTTON_STATE_PRESSED ) { // if off request in a valid mode, send to UI for user confirmation if ( TRUE == isCurrentOpModeOkToTurnOff() ) @@ -308,9 +291,10 @@ #endif } } - prevOffButtonState = offButtonState; + prevOffButtonState = getOffButtonState(); } + // if user confirmed off button press, manage off request sequence if ( TRUE == offButtonPressPending ) { offRequestPulseTimer += TASK_PRIORITY_INTERVAL; @@ -340,14 +324,14 @@ static void handleStopButtonProcessing( void ) { // handle button state transitions for stop button - if ( stopButtonState != prevStopButtonState ) + if ( getStopButtonState() != prevStopButtonState ) { - if ( stopButtonState == BUTTON_STATE_PRESSED ) + if ( getStopButtonState() == BUTTON_STATE_PRESSED ) { stopButtonPressPending = TRUE; stopButtonPendingTimer = getMSTimerCount(); } - prevStopButtonState = stopButtonState; + prevStopButtonState = getStopButtonState(); } // handle when a stop button press is pending @@ -361,3 +345,110 @@ } } + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/************************************************************************* + * @brief testSetOffButtonStateOverride + * The testSetOffButtonStateOverride function overrides the state of the \n + * off button with a given state. + * @details + * Inputs : none + * Outputs : dataOffButtonState + * @param state : override state for the off button + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetOffButtonStateOverride( BUTTON_STATE_T state ) +{ + BOOL result = FALSE; + + // verify test login successfully completed before executing override + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataOffButtonState.ovData = state; + dataOffButtonState.override = OVERRIDE_KEY; + } + + return result; +} + +/************************************************************************* + * @brief testResetOffButtonStateOverride + * The testResetOffButtonStateOverride function resets the override of the \n + * state of the off button. + * @details + * Inputs : none + * Outputs : dataOffButtonState + * @param none + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetOffButtonStateOverride( void ) +{ + BOOL result = FALSE; + + // verify test login successfully completed before executing override reset + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataOffButtonState.override = OVERRIDE_RESET; + dataOffButtonState.ovData = dataOffButtonState.ovInitData; + } + + return result; +} + +/************************************************************************* + * @brief testSetStopButtonStateOverride + * The testSetStopButtonStateOverride function overrides the state of the \n + * stop button with a given state. + * @details + * Inputs : none + * Outputs : dataStopButtonState + * @param state : override state for the stop button + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetStopButtonStateOverride( BUTTON_STATE_T state ) +{ + BOOL result = FALSE; + + // verify test login successfully completed before executing override + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataStopButtonState.ovData = state; + dataStopButtonState.override = OVERRIDE_KEY; + } + + return result; +} + +/************************************************************************* + * @brief testResetStopButtonStateOverride + * The testResetStopButtonStateOverride function resets the override of the \n + * state of the stop button. + * @details + * Inputs : none + * Outputs : dataStopButtonState + * @param none + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetStopButtonStateOverride( void ) +{ + BOOL result = FALSE; + + // verify test login successfully completed before executing override reset + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataStopButtonState.override = OVERRIDE_RESET; + dataStopButtonState.ovData = dataStopButtonState.ovInitData; + } + + return result; +} + Index: App/Controllers/Buttons.h =================================================================== diff -u -r3323966fe741edbb36dffc78317ccf06ed93a68e -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Controllers/Buttons.h (.../Buttons.h) (revision 3323966fe741edbb36dffc78317ccf06ed93a68e) +++ App/Controllers/Buttons.h (.../Buttons.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -21,20 +21,27 @@ // ********** public definitions ********** -typedef enum Buttons +typedef enum Button_States { - BUTTON_OFF = 0, // Off button - BUTTON_STOP, // Stop button - NUM_OF_BUTTONS -} BUTTON_T; + BUTTON_STATE_RELEASED = 0, + BUTTON_STATE_PRESSED, + NUM_OF_BUTTON_STATES +} BUTTON_STATE_T; // ********** public function prototypes ********** void initButtons( void ); void execButtons( void ); BOOL isStopButtonPressed( void ); -BOOL isButtonPressedRaw( BUTTON_T button ); void userConfirmOffButton( U08 response ); SELF_TEST_STATUS_T execStuckButtonTest( void ); +DATA_GET_PROTOTYPE( BUTTON_STATE_T, getOffButtonState ); +DATA_GET_PROTOTYPE( BUTTON_STATE_T, getStopButtonState ); + +BOOL testSetOffButtonStateOverride( BUTTON_STATE_T state ); +BOOL testResetOffButtonStateOverride( void ); +BOOL testSetStopButtonStateOverride( BUTTON_STATE_T state ); +BOOL testResetStopButtonStateOverride( void ); + #endif Index: App/Services/CommBuffers.c =================================================================== diff -u -ra0f8a69651a1c29c9f76894aed5ab23ee8ace7c7 -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/CommBuffers.c (.../CommBuffers.c) (revision a0f8a69651a1c29c9f76894aed5ab23ee8ace7c7) +++ App/Services/CommBuffers.c (.../CommBuffers.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -74,6 +74,8 @@ * The addToCommBuffer function adds data of specified length to a specified \n * communication buffer. S/W fault if buffer too full to add data. \n * This function will always add to the active double buffer. \n + * This function should only be called from the background, general, or \n + * priority tasks (BG or IRQ) for thread safety. * @details * Inputs : commBufferByteCount[], activeDoubleBuffer[] * Outputs : commBuffers[], commBufferByteCount[] Index: App/Services/CommBuffers.h =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/CommBuffers.h (.../CommBuffers.h) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ App/Services/CommBuffers.h (.../CommBuffers.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -34,8 +34,8 @@ COMM_BUFFER_IN_CAN_DG_BROADCAST, COMM_BUFFER_IN_CAN_UI_2_HD, COMM_BUFFER_IN_CAN_UI_BROADCAST, - COMM_BUFFER_IN_DBG, - COMM_BUFFER_OUT_DBG, + COMM_BUFFER_IN_UART_PC, + COMM_BUFFER_OUT_UART_PC, NUM_OF_COMM_BUFFERS } COMM_BUFFER_T; Index: App/Services/CommInterrupts.c =================================================================== diff -u --- App/Services/CommInterrupts.c (revision 0) +++ App/Services/CommInterrupts.c (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -0,0 +1,108 @@ +/************************************************************************** + * + * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * @file FPGA.c + * + * @date 22-Oct-2019 + * @author S. Nash + * + * @brief Communications Interrupts service module. Provides communication \n + * interrupt handling functions. + * + **************************************************************************/ + +#include "sci.h" +#include "sys_dma.h" + +#include "CommInterrupts.h" +#include "FPGA.h" +#include "SystemComm.h" + +// ********** private definitions ********** + + +// ********** private data ********** + +static U32 frameErrorCnt = 0; +static U32 overrunErrorCnt = 0; + + +// ********** private function prototypes ********** + + +/************************************************************************* + * @brief sciNotification + * The sciNotification function handles UART communication error interrupts. \n + * Frame and Over-run errors are handled. + * @details + * Inputs : none + * Outputs : UART error interrupts handled. + * @param sci : Pointer to the SCI peripheral that detected the error + * @param flags : error flag(s) + * @return none + *************************************************************************/ +void sciNotification(sciBASE_t *sci, uint32 flags) +{ + if ( ( flags & SCI_FE_INT ) != 0 ) + { + frameErrorCnt++; + } + if ( ( flags & SCI_OE_INT ) != 0 ) + { + overrunErrorCnt++; + } +} + +/************************************************************************* + * @brief dmaGroupANotification + * The dmaGroupANotification function handles communication DMA interrupts. + * @details + * Inputs : none + * Outputs : DMA interrupt is handled. + * @param inttype : type of DMA interrupt + * @param channel : DMA channel that caused the interrupt + * @return none + *************************************************************************/ +void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel) +{ + if ( inttype == BTC ) // block transfer completed interrupt + { + switch ( channel ) + { + case DMA_CH0: // FPGA receive channel + // clear DMA receipt + scilinREG->CLEARINT = SCI_DMA_RECEIVE_INT; + signalFPGAReceiptCompleted(); + break; + + case DMA_CH1: // PC receive channel + // clear DMA receipt + sciREG->CLEARINT = SCI_DMA_RECEIVE_INT; + // handle received packet from PC + handleUARTMsgRecvPacketInterrupt(); + break; + + case DMA_CH2: // FPGA transmit channel + // clear DMA xmit + scilinREG->CLEARINT = SCI_DMA_TRANSMIT_INT; + signalFPGATransmitCompleted(); + break; + + case DMA_CH3: // PC transmit channel + // clear DMA xmit + sciREG->CLEARINT = SCI_DMA_TRANSMIT_INT; + // send next pending packet to PC (if any) + handleUARTMsgXmitPacketInterrupt(); + break; + + default: + // TODO - ignore? + break; + } + } +} + Index: App/Services/CommInterrupts.h =================================================================== diff -u --- App/Services/CommInterrupts.h (revision 0) +++ App/Services/CommInterrupts.h (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * @file CommInterrupts.h + * + * @date 22-Oct-2019 + * @author S. Nash + * + * @brief header file for communication interrupts service. + * + **************************************************************************/ + +#ifndef __COMM_INTERRUPTS_H__ +#define __COMM_INTERRUPTS_H__ + +#include "Common.h" + +// ********** public definitions ********** + +#define SCI_DMA_TRANSMIT_INT 0x00010000 +#define SCI_DMA_RECEIVE_INT 0x00060000 + +#define SCI1_TX_BUSY() ( ( sciREG->FLR & (uint32)SCI_TX_INT ) == 0U ? TRUE : FALSE ) +#define SCI1_TX_DMA_BUSY() ( ( sciREG->CLEARINT & SCI_DMA_RECEIVE_INT ) != 0 ? TRUE : FALSE ) +#define SCI1_TX_IN_PROGRESS() ( ( SCI1_TX_BUSY() == TRUE ) || ( SCI1_TX_DMA_BUSY() == TRUE ) ? TRUE : FALSE ) + +#define SCI2_TX_BUSY() ( ( scilinREG->FLR & (uint32)SCI_TX_INT ) == 0U ? TRUE : FALSE ) +#define SCI2_TX_DMA_BUSY() ( ( scilinREG->CLEARINT & SCI_DMA_RECEIVE_INT ) != 0 ? TRUE : FALSE ) +#define SCI2_TX_IN_PROGRESS() ( ( SCI2_TX_BUSY() == TRUE ) || ( SCI2_TX_DMA_BUSY() == TRUE ) ? TRUE : FALSE ) + +// ********** public function prototypes ********** + +#endif Index: App/Services/FPGA.c =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/FPGA.c (.../FPGA.c) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ App/Services/FPGA.c (.../FPGA.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -16,20 +16,46 @@ * **************************************************************************/ -#include // for memcpy() +//#include // for memcpy() #include "sci.h" #include "sys_dma.h" -#include "Common.h" +#include "CommInterrupts.h" +#include "SystemCommMessages.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_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_READ_CMD_BUFFER_LEN 8 -#define FPGA_WRITE_RSP_BUFFER_LEN 10 +#define FPGA_WRITE_RSP_BUFFER_LEN 8 #define FPGA_READ_RSP_BUFFER_LEN 100 +#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_CRC_LEN 2 +#define FPGA_WRITE_CMD_HDR_LEN 5 +#define FPGA_READ_CMD_HDR_LEN 4 +#define FPGA_WRITE_RSP_HDR_LEN 1 +#define FPGA_READ_RSP_HDR_LEN 1 + #define SCI2_RECEIVE_DMA_REQUEST 28 #define SCI2_TRANSMIT_DMA_REQUEST 29 @@ -44,18 +70,27 @@ typedef struct { U08 artBloodValveState; // arterial blood valve set state + U08 venBloodValveState; // venous blood valve set state } FPGA_ACTUATORS_T; #pragma pack(pop) // ********** private data ********** +// FPGA state +static FPGA_STATE_T fpgaState = FPGA_STATE_START; + +static U32 fpgaReceiptCounter = 0; +static U32 fpgaTransmitCounter = 0; + // FPGA received sensor data from DMA bulk read -static FPGA_SENSORS_T fpgaSensors; +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,0,0}; +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 fpgaReadResponseBuffer[FPGA_READ_RSP_BUFFER_LEN]; // DMA control records @@ -66,20 +101,33 @@ // FPGA data -U08 version; // FPGA version -U08 diagnostic; // FPGA diagnostic register +U08 fpgaId; // FPGA Id +U08 fpgaRev; // FPGA Revision +U08 fpgaDiag; // FPGA diagnostic register -DATA_DECL( TWO_WAY_STATE_T, BloodValveState, dataArterialBloodValveState, STATE_CLOSED, STATE_CLOSED ); +// 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 handleFPGAWriteAllActuatorsState( void ); +static FPGA_STATE_T handleFPGAReceiveAllSensorsState( void ); + static void setupDMAForWriteCmd( U32 bytes2Transmit ); static void startDMAWriteCmd( void ); static void setupDMAForWriteResp( U32 bytes2Receive ); static void startDMAReceiptOfWriteResp( void ); static void setupDMAForReadCmd( U32 bytes2Transmit ); static void startDMAReadCmd( void ); static void setupDMAForReadResp( U32 bytes2Receive ); +static void startDMAReceiptOfReadResp( void ); /************************************************************************* * @brief initFPGA @@ -92,39 +140,35 @@ *************************************************************************/ void initFPGA( void ) { - sciEnableLoopback( scilinREG, Digital_Lbk ); // TODO - for test only - // enable interrupt notifications for FPGA serial port - //sciEnableNotification( scilinREG, SCI_TX_INT | SCI_RX_INT | SCI_OE_INT | SCI_FE_INT ); - //sciEnableNotification( scilinREG, SCI_RX_INT | SCI_OE_INT | SCI_FE_INT ); sciEnableNotification( scilinREG, SCI_OE_INT | SCI_FE_INT ); - // Enable DMA block transfer complete interrupts - dmaEnableInterrupt( DMA_CH0, BTC ); - dmaEnableInterrupt( DMA_CH2, BTC ); // assign DMA channels to h/w DMA requests dmaReqAssign( DMA_CH0, SCI2_RECEIVE_DMA_REQUEST ); dmaReqAssign( DMA_CH2, SCI2_TRANSMIT_DMA_REQUEST ); // set DMA channel priorities dmaSetPriority( DMA_CH0, HIGHPRIORITY ); dmaSetPriority( DMA_CH2, LOWPRIORITY ); + // Enable DMA block transfer complete interrupts + dmaEnableInterrupt( DMA_CH0, BTC ); + dmaEnableInterrupt( DMA_CH2, BTC ); // initialize FPGA DMA Write Control Record fpgaDMAWriteControlRecord.PORTASGN = 4; // port B (only choice per datasheet) + fpgaDMAWriteControlRecord.SADD = (U32)fpgaWriteCmdBuffer; // transfer source address fpgaDMAWriteControlRecord.DADD = (U32)(&(scilinREG->TD)); // dest. is SCI2 xmit register - fpgaDMAWriteControlRecord.SADD = (U32)fpgaWriteResponseBuffer; // transfer source address fpgaDMAWriteControlRecord.CHCTRL = 0; // no chaining fpgaDMAWriteControlRecord.ELCNT = 1; // frame is 1 element fpgaDMAWriteControlRecord.FRCNT = 0; // block is TBD frames - will be populated later when known fpgaDMAWriteControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte fpgaDMAWriteControlRecord.WRSIZE = ACCESS_8_BIT; // fpgaDMAWriteControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer - fpgaDMAWriteControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed fpgaDMAWriteControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment + fpgaDMAWriteControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed fpgaDMAWriteControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - fpgaDMAWriteControlRecord.ELSOFFSET = 0; // # of bytes to advance at source memory after each element + fpgaDMAWriteControlRecord.ELSOFFSET = 0; // not used fpgaDMAWriteControlRecord.ELDOFFSET = 0; // not used - fpgaDMAWriteControlRecord.FRSOFFSET = 0; // # of bytes to advance at source memory after each frame + fpgaDMAWriteControlRecord.FRSOFFSET = 0; // not used fpgaDMAWriteControlRecord.FRDOFFSET = 0; // not used // initialize FPGA DMA Write Response Control Record @@ -140,33 +184,33 @@ fpgaDMAWriteRespControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed fpgaDMAWriteRespControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment fpgaDMAWriteRespControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - fpgaDMAWriteRespControlRecord.ELDOFFSET = 0; // # of bytes to advance at destination memory after each element + fpgaDMAWriteRespControlRecord.ELDOFFSET = 0; // not used fpgaDMAWriteRespControlRecord.ELSOFFSET = 0; // not used - fpgaDMAWriteRespControlRecord.FRDOFFSET = 0; // # of bytes to advance at destination memory after each frame + fpgaDMAWriteRespControlRecord.FRDOFFSET = 0; // not used fpgaDMAWriteRespControlRecord.FRSOFFSET = 0; // not used // initialize FPGA DMA Read Control Record fpgaDMAReadControlRecord.PORTASGN = 4; // port B (only choice per datasheet) + fpgaDMAReadControlRecord.SADD = (U32)fpgaReadCmdBuffer; // transfer source address fpgaDMAReadControlRecord.DADD = (U32)(&(scilinREG->TD)); // dest. is SCI2 xmit register - fpgaDMAReadControlRecord.SADD = (U32)fpgaWriteResponseBuffer;// transfer source address fpgaDMAReadControlRecord.CHCTRL = 0; // no chaining fpgaDMAReadControlRecord.ELCNT = 1; // frame is 1 element fpgaDMAReadControlRecord.FRCNT = 0; // block is TBD frames - will be populated later when known fpgaDMAReadControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte fpgaDMAReadControlRecord.WRSIZE = ACCESS_8_BIT; // fpgaDMAReadControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer - fpgaDMAReadControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed fpgaDMAReadControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment + fpgaDMAReadControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed fpgaDMAReadControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - fpgaDMAReadControlRecord.ELSOFFSET = 0; // # of bytes to advance at source memory after each element + fpgaDMAReadControlRecord.ELSOFFSET = 0; // not used fpgaDMAReadControlRecord.ELDOFFSET = 0; // not used - fpgaDMAReadControlRecord.FRSOFFSET = 0; // # of bytes to advance at source memory after each frame + fpgaDMAReadControlRecord.FRSOFFSET = 0; // not used fpgaDMAReadControlRecord.FRDOFFSET = 0; // not used // initialize FPGA DMA Read Response Control Record fpgaDMAReadRespControlRecord.PORTASGN = 4; // port B (only choice per datasheet) fpgaDMAReadRespControlRecord.SADD = (U32)(&(scilinREG->RD)); // source is SCI2 recv register - fpgaDMAReadRespControlRecord.DADD = (U32)fpgaWriteResponseBuffer; // transfer destination address + fpgaDMAReadRespControlRecord.DADD = (U32)fpgaReadResponseBuffer; // transfer destination address fpgaDMAReadRespControlRecord.CHCTRL = 0; // no chaining fpgaDMAReadRespControlRecord.ELCNT = 1; // frame is 1 element fpgaDMAReadRespControlRecord.FRCNT = 0; // block is TBD frames - will be populated later when known @@ -176,19 +220,49 @@ fpgaDMAReadRespControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed fpgaDMAReadRespControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment fpgaDMAReadRespControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - fpgaDMAReadRespControlRecord.ELDOFFSET = 0; // # of bytes to advance at destination memory after each element + fpgaDMAReadRespControlRecord.ELDOFFSET = 0; // not used fpgaDMAReadRespControlRecord.ELSOFFSET = 0; // not used - fpgaDMAReadRespControlRecord.FRDOFFSET = 0; // # of bytes to advance at destination memory after each frame + fpgaDMAReadRespControlRecord.FRDOFFSET = 0; // not used fpgaDMAReadRespControlRecord.FRSOFFSET = 0; // not used // TODO - this is a DMA xmit and recv via loopback test - setupDMAForWriteResp( 8 ); - startDMAReceiptOfWriteResp(); - setupDMAForWriteCmd( 8 ); - startDMAWriteCmd(); +// setupDMAForWriteResp( 8 ); +// setupDMAForWriteCmd( 8 ); +// startDMAReceiptOfWriteResp(); +// startDMAWriteCmd(); } /************************************************************************* + * @brief signalFPGAReceiptCompleted + * The signalFPGAReceiptCompleted function increments a counter to indicate \n + * that another DMA receipt from the FPGA has completed. + * @details + * Inputs : none + * Outputs : fpgaReceiptCounter + * @param none + * @return none + *************************************************************************/ +void signalFPGAReceiptCompleted( void ) +{ + fpgaReceiptCounter++; +} + +/************************************************************************* + * @brief signalFPGATransmitCompleted + * The signalFPGATransmitCompleted function increments a counter to indicate \n + * that another DMA transmit to the FPGA has completed. + * @details + * Inputs : none + * Outputs : fpgaReceiptCounter + * @param none + * @return none + *************************************************************************/ +void signalFPGATransmitCompleted( void ) +{ + fpgaTransmitCounter++; +} + +/************************************************************************* * @brief execFPGA * The execFPGA function manages data exchanges with the FPGA. * @details @@ -199,113 +273,416 @@ *************************************************************************/ void execFPGA( void ) { - U08 x; - x = fpgaWriteResponseBuffer[0]; + switch ( fpgaState ) + { + case FPGA_STATE_START: + fpgaState = FPGA_STATE_READ_VERS_AND_DIAG; + break; + + case FPGA_STATE_READ_VERS_AND_DIAG: + fpgaState = handleFPGAReadVersionAndDiagnosticState(); + 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(); + break; + + case FPGA_STATE_FAILED: + // do nothing - we'll be stuck here + break; + + default: + // TODO - fault + break; + } } +/************************************************************************* + * @brief handleFPGAReadVersionAndDiagnosticState + * The handleFPGAReadVersionAndDiagnosticState function handles the FPGA state \n + * where the read version/diag 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 ) +{ + FPGA_STATE_T result = FPGA_STATE_RCV_VERS_AND_DIAG; + // 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 + // prep DMA for sending the read cmd and receiving the response + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + 3 + FPGA_CRC_LEN ); + setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); + startDMAReceiptOfReadResp(); + startDMAReadCmd(); + return result; +} +/************************************************************************* + * @brief handleFPGAReceiveVersionAndDiagnosticState + * The handleFPGAReceiveVersionAndDiagnosticState function handles the FPGA state \n + * where the version/diag read response should be ready to parse. + * @details + * Inputs : none + * Outputs : version/diag values updated + * @param none + * @return next FPGA state + *************************************************************************/ +static FPGA_STATE_T handleFPGAReceiveVersionAndDiagnosticState( void ) +{ + FPGA_STATE_T result = FPGA_STATE_READ_VERS_AND_DIAG; + // did 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]; + result = FPGA_STATE_WRITE_ALL_ACTUATORS; + } + } + } + + return result; +} + +/************************************************************************* + * @brief handleFPGAWriteAllActuatorsState + * The handleFPGAWriteAllActuatorsState function handles the FPGA state \n + * where the bulk write command is sent to the FPGA. + * @details + * Inputs : actuator set points + * Outputs : actuator set points sent to FPGA + * @param none + * @return next FPGA state + *************************************************************************/ +static FPGA_STATE_T handleFPGAWriteAllActuatorsState( void ) +{ + FPGA_STATE_T result = FPGA_STATE_RCV_ALL_SENSORS; + + return result; +} + +/************************************************************************* + * @brief handleFPGAReceiveAllSensorsState + * The handleFPGAReceiveAllSensorsState function handles the FPGA state \n + * where the bulk read response should be ready to parse. + * @details + * Inputs : none + * Outputs : sensor values updated + * @param none + * @return next FPGA state + *************************************************************************/ +static FPGA_STATE_T handleFPGAReceiveAllSensorsState( void ) +{ + FPGA_STATE_T result = FPGA_STATE_WRITE_ALL_ACTUATORS; + + return result; +} + +/************************************************************************* + * @brief setupDMAForWriteCmd + * The setupDMAForWriteCmd function sets the byte count for the next DMA \n + * write command to the FPGA. + * @details + * Inputs : none + * Outputs : # of bytes for next FPGA write command is set + * @param bytes2Transmit : # of bytes to be transmitted via DMA to the FPGA. + * @return none + *************************************************************************/ static void setupDMAForWriteCmd( U32 bytes2Transmit ) { fpgaDMAWriteControlRecord.FRCNT = bytes2Transmit; } +/************************************************************************* + * @brief startDMAWriteCmd + * The startDMAWriteCmd function initiates the DMA transmit for the next \n + * DMA write command to the FPGA. + * @details + * Inputs : none + * Outputs : DMA write command to FPGA is initiated + * @param none + * @return none + *************************************************************************/ static void startDMAWriteCmd( void ) { dmaSetCtrlPacket( DMA_CH2, fpgaDMAWriteControlRecord ); dmaSetChEnable( DMA_CH2, DMA_HW ); - scilinREG->SETINT = (uint32)((uint32)1U << 16U); /* Tx DMA */ + scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; } +/************************************************************************* + * @brief setupDMAForWriteResp + * The setupDMAForWriteResp function sets the expected byte count for the \n + * next DMA write command response from the FPGA. + * @details + * Inputs : none + * Outputs : # of expected bytes for next FPGA write command response is set + * @param bytes2Receive : # of bytes expected to be transmitted via DMA from the FPGA. + * @return none + *************************************************************************/ static void setupDMAForWriteResp( U32 bytes2Receive ) { fpgaDMAWriteRespControlRecord.FRCNT = bytes2Receive; } +/************************************************************************* + * @brief startDMAReceiptOfWriteResp + * The startDMAReceiptOfWriteResp function initiates readiness of the DMA \n + * receiver for the next DMA write command response from the FPGA. + * @details + * Inputs : none + * Outputs : DMA write command response is ready to be received from the FPGA + * @param none + * @return none + *************************************************************************/ static void startDMAReceiptOfWriteResp( void ) { dmaSetCtrlPacket( DMA_CH0, fpgaDMAWriteRespControlRecord ); dmaSetChEnable( DMA_CH0, DMA_HW ); - scilinREG->SETINT = (uint32)((uint32)1U << 18U); /* Rx DMA All */ - scilinREG->SETINT = (uint32)((uint32)1U << 17U); /* Rx DMA */ + scilinREG->SETINT = SCI_DMA_RECEIVE_INT; } +/************************************************************************* + * @brief setupDMAForReadCmd + * The setupDMAForReadCmd function sets the byte count for the next DMA \n + * read command to the FPGA. + * @details + * Inputs : none + * Outputs : # of bytes for next FPGA read command is set + * @param bytes2Transmit : # of bytes to be transmitted via DMA to the FPGA. + * @return none + *************************************************************************/ static void setupDMAForReadCmd( U32 bytes2Transmit ) { fpgaDMAReadControlRecord.FRCNT = bytes2Transmit; } +/************************************************************************* + * @brief startDMAReadCmd + * The startDMAReadCmd function initiates the DMA transmit for the next \n + * DMA read command to the FPGA. + * @details + * Inputs : none + * Outputs : DMA read command to FPGA is initiated + * @param none + * @return none + *************************************************************************/ static void startDMAReadCmd( void ) { dmaSetCtrlPacket( DMA_CH2, fpgaDMAReadControlRecord ); dmaSetChEnable( DMA_CH2, DMA_HW ); - scilinREG->SETINT = (uint32)((uint32)1U << 16U); /* Tx DMA */ + scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; } +/************************************************************************* + * @brief setupDMAForReadResp + * The setupDMAForReadResp function sets the expected byte count for the \n + * next DMA read command response from the FPGA. + * @details + * Inputs : none + * Outputs : # of expected bytes for next FPGA read command response is set + * @param bytes2Receive : # of expected bytes to be transmitted via DMA from the FPGA. + * @return none + *************************************************************************/ static void setupDMAForReadResp( U32 bytes2Receive ) { fpgaDMAReadRespControlRecord.FRCNT = bytes2Receive; } +/************************************************************************* + * @brief startDMAReceiptOfReadResp + * The startDMAReceiptOfReadResp function initiates readiness of the DMA \n + * receiver for the next DMA read command response from the FPGA. + * @details + * Inputs : none + * Outputs : DMA read command response is ready to be received from the FPGA + * @param none + * @return none + *************************************************************************/ static void startDMAReceiptOfReadResp( void ) { dmaSetCtrlPacket( DMA_CH0, fpgaDMAReadRespControlRecord ); dmaSetChEnable( DMA_CH0, DMA_HW ); - scilinREG->SETINT = (uint32)((uint32)1U << 18U); /* Rx DMA All */ - scilinREG->SETINT = (uint32)((uint32)1U << 17U); /* Rx DMA */ + scilinREG->SETINT = SCI_DMA_RECEIVE_INT; } - - -U08 getFPGAVersion( void ) +/************************************************************************* + * @brief getFPGAId + * The getFPGAId function gets the version read from the Id register \n + * of the FPGA. + * @details + * Inputs : fpgaId + * Outputs : none + * @param none + * @return Id + *************************************************************************/ +U08 getFPGAId( void ) { + return fpgaId; +} +/************************************************************************* + * @brief getFPGARev + * The getFPGARev function gets the revision read from the Rev register \n + * of the FPGA. + * @details + * Inputs : fpgaRev + * Outputs : none + * @param none + * @return Revision + *************************************************************************/ +U08 getFPGARev( void ) +{ + return fpgaRev; } +/************************************************************************* + * @brief getFPGADiag + * The getFPGADiag function gets the version read from the diagnostic register \n + * of the FPGA. + * @details + * Inputs : fpgaDiag + * Outputs : none + * @param none + * @return fpgaDiag + *************************************************************************/ U08 getFPGADiag( void ) { - U08 result = 0; - - return result; + return fpgaDiag; } -void setFPGADiag( void ) -{ +/************************************************************************* + * @brief getArterialBloodValveState + * The getArterialBloodValveState function gets the latest arterial blood \n + * valve state read from the FPGA. + * @details + * Inputs : dataArterialBloodValveState + * Outputs : none + * @param none + * @return The last read state for the arterial blood valve + *************************************************************************/ +DATA_GET( OPN_CLS_STATE_T, getArterialBloodValveState, dataArterialBloodValveState ) -} +/************************************************************************* + * @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 ) -DATA_GET( TWO_WAY_STATE_T, getArterialBloodValveState, dataArterialBloodValveState ) +/************************************************************************* + * @brief getVenousBloodValveState + * The getVenousBloodValveState function gets the latest venous blood \n + * valve state read from the FPGA. + * @details + * Inputs : dataVenousBloodValveState + * Outputs : none + * @param none + * @return The last read state for the venous blood valve + *************************************************************************/ +DATA_GET( OPN_CLS_STATE_T, getVenousBloodValveState, dataVenousBloodValveState ) -BOOL dialinSetArterialBloodValveStateOverride( TWO_WAY_STATE_T state ) -{ - BOOL result = FALSE; +/************************************************************************* + * @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 ) - // verify dialin login successfully completed before executing override - if ( 1 ) // TODO - call function to check login - { - result = TRUE; - dataArterialBloodValveState.ovData = state; - dataArterialBloodValveState.override = OVERRIDE_KEY; - } - return result; -} -BOOL dialinResetArterialBloodValveStateOverride( void ) -{ - BOOL result = FALSE; - // verify dialin login successfully completed before executing override reset - if ( 1 ) // TODO - call function to check login - { - result = TRUE; - dataArterialBloodValveState.override = OVERRIDE_RESET; - dataArterialBloodValveState.ovData = dataArterialBloodValveState.ovInitData; - } +/************************************************************************* + * @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 ) - return result; -} +/************************************************************************* + * @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 ) + + Index: App/Services/FPGA.h =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/FPGA.h (.../FPGA.h) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ App/Services/FPGA.h (.../FPGA.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -10,30 +10,43 @@ * @date 21-Oct-2019 * @author S. Nash * - * @brief header file for FPGA Interface service . + * @brief header file for FPGA Interface service. * **************************************************************************/ #ifndef __FPGA_H__ #define __FPGA_H__ #include "Common.h" +#include "CommInterrupts.h" // ********** public definitions ********** - // ********** public function prototypes ********** void initFPGA( void ); void execFPGA( void ); +void signalFPGAReceiptCompleted( void ); +void signalFPGATransmitCompleted( void ); -U08 getFPGAVersion( void ); +U08 getFPGAId( void ); +U08 getFPGARev( void ); U08 getFPGADiag( void ); -void setFPGADiag( void ); -DATA_GET_PROTOTYPE( TWO_WAY_STATE_T, getArterialBloodValveState ); +DATA_GET_PROTOTYPE( OPN_CLS_STATE_T, getArterialBloodValveState ); +DATA_GET_PROTOTYPE( OPN_CLS_STATE_T, getArterialBloodValveSetState ); -BOOL dialinSetArterialBloodValveStateOverride( TWO_WAY_STATE_T state ); -BOOL dialinResetArterialBloodValveStateOverride( void ); +DATA_GET_PROTOTYPE( OPN_CLS_STATE_T, getVenousBloodValveState ); +DATA_GET_PROTOTYPE( OPN_CLS_STATE_T, getVenousBloodValveSetState ); +BOOL testSetArterialBloodValveStateOverride( OPN_CLS_STATE_T state ); +BOOL testResetArterialBloodValveStateOverride( void ); +BOOL testSetArterialBloodValveSetStateOverride( OPN_CLS_STATE_T state ); +BOOL testResetArterialBloodValveSetStateOverride( void ); + +BOOL testSetVenousBloodValveStateOverride( OPN_CLS_STATE_T state ); +BOOL testResetVenousBloodValveStateOverride( void ); +BOOL testSetVenousBloodValveSetStateOverride( OPN_CLS_STATE_T state ); +BOOL testResetVenousBloodValveSetStateOverride( void ); + #endif Index: App/Services/MsgQueues.h =================================================================== diff -u -r833095dbbe2b21a989b05f48bd7ddc390ad964cb -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/MsgQueues.h (.../MsgQueues.h) (revision 833095dbbe2b21a989b05f48bd7ddc390ad964cb) +++ App/Services/MsgQueues.h (.../MsgQueues.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -21,12 +21,11 @@ // ********** public definitions ********** -#define MAX_MSG_CARGO_SIZE 100 // bytes +#define MAX_MSG_CARGO_SIZE 100 // bytes typedef enum Msg_Queues { - MSG_Q_IN_CAN = 0, - MSG_Q_IN_DBG, + MSG_Q_IN = 0, NUM_OF_MSG_QUEUES } MSG_QUEUE_T; Index: App/Services/SystemComm.c =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/SystemComm.c (.../SystemComm.c) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ App/Services/SystemComm.c (.../SystemComm.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -22,10 +22,10 @@ #include "sci.h" #include "sys_dma.h" -#include "Common.h" +#include "SystemComm.h" +#include "CommInterrupts.h" #include "MsgQueues.h" #include "SystemCommMessages.h" -#include "SystemComm.h" #ifdef RM46_EVAL_BOARD_TARGET #include "CPLD.h" @@ -35,10 +35,13 @@ #define NUM_OF_CAN_OUT_BUFFERS 4 // # of CAN buffers for transmit #define NUM_OF_CAN_IN_BUFFERS 6 // # of CAN buffers for receiving +#define NUM_OF_MSG_IN_BUFFERS 7 // # of Msg buffers for receiving #define SCI1_RECEIVE_DMA_REQUEST 30 #define SCI1_TRANSMIT_DMA_REQUEST 31 +#define CAN_TX_BUSY() ( ( canREG1->TXRQx[0] != 0 ) || ( canREG1->TXRQx[1] != 0 ) ? TRUE : FALSE ) + // ********** private data ********** const COMM_BUFFER_T CAN_OUT_BUFFERS[NUM_OF_CAN_OUT_BUFFERS] = @@ -49,28 +52,27 @@ COMM_BUFFER_OUT_CAN_HD_BROADCAST }; -const COMM_BUFFER_T CAN_IN_BUFFERS[NUM_OF_CAN_IN_BUFFERS] = +const COMM_BUFFER_T MSG_IN_BUFFERS[NUM_OF_MSG_IN_BUFFERS] = { COMM_BUFFER_IN_CAN_DG_ALARM, COMM_BUFFER_IN_CAN_UI_ALARM, COMM_BUFFER_IN_CAN_DG_2_HD, COMM_BUFFER_IN_CAN_DG_BROADCAST, COMM_BUFFER_IN_CAN_UI_2_HD, - COMM_BUFFER_IN_CAN_UI_BROADCAST + COMM_BUFFER_IN_CAN_UI_BROADCAST, + COMM_BUFFER_IN_UART_PC }; -static U08 pcXmitPacket[PC_MESSAGE_PACKET_SIZE]; -static U08 pcRecvPacket[PC_MESSAGE_PACKET_SIZE]; +static U08 pcXmitPacket[PC_MESSAGE_PACKET_SIZE] = {0,0,0,0,0,0,0,0};// = {1,2,3,4,5,6,7,8}; +static U08 pcRecvPacket[PC_MESSAGE_PACKET_SIZE] = {0,0,0,0,0,0,0,0}; // DMA control records static g_dmaCTRL pcDMAXmitControlRecord; static g_dmaCTRL pcDMARecvControlRecord; // ********** private function prototypes ********** -static void handleCANPacketReceivedInt( CAN_MESSAGE_BOX_T srcCANBox ); -static void handleCANXmitCompleteInt( void ); -static void handleUARTXmitCompleteInt( void ); +static void initUARTAndDMA( void ); static BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox ); static BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox ); @@ -95,53 +97,13 @@ *************************************************************************/ void initSystemComm( void ) { - sciEnableLoopback( sciREG, Digital_Lbk ); // TODO - for test only + // initialize UART and DMA for PC communication + initUARTAndDMA(); - // Enable DMA block transfer complete interrupts - dmaEnableInterrupt( DMA_CH1, BTC ); - dmaEnableInterrupt( DMA_CH3, BTC ); - // assign DMA channels to h/w DMA requests - dmaReqAssign( DMA_CH1, SCI1_RECEIVE_DMA_REQUEST ); - dmaReqAssign( DMA_CH3, SCI1_TRANSMIT_DMA_REQUEST ); - // set DMA channel priorities - dmaSetPriority( DMA_CH1, HIGHPRIORITY ); - dmaSetPriority( DMA_CH3, LOWPRIORITY ); - - // initialize PC DMA Transmit Control Record - pcDMAXmitControlRecord.PORTASGN = 4; // port B (only choice per datasheet) - pcDMAXmitControlRecord.DADD = (U32)(&(sciREG->TD)); // dest. is SCI2 xmit register - pcDMAXmitControlRecord.SADD = (U32)pcXmitPacket; // source - pcDMAXmitControlRecord.CHCTRL = 0; // no chaining - pcDMAXmitControlRecord.ELCNT = 1; // frame is 1 element - pcDMAXmitControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames - pcDMAXmitControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte - pcDMAXmitControlRecord.WRSIZE = ACCESS_8_BIT; // - pcDMAXmitControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer - pcDMAXmitControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed - pcDMAXmitControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment - pcDMAXmitControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - pcDMAXmitControlRecord.ELSOFFSET = 0; // # of bytes to advance at source memory after each element - pcDMAXmitControlRecord.ELDOFFSET = 0; // not used - pcDMAXmitControlRecord.FRSOFFSET = 0; // # of bytes to advance at source memory after each frame - pcDMAXmitControlRecord.FRDOFFSET = 0; // not used - - // initialize PC DMA Receipt Control Record - pcDMARecvControlRecord.PORTASGN = 4; // port B (only choice per datasheet) - pcDMARecvControlRecord.SADD = (U32)(&(sciREG->RD));// source is SCI2 recv register - pcDMARecvControlRecord.DADD = (U32)pcRecvPacket; // transfer destination address - pcDMARecvControlRecord.CHCTRL = 0; // no chaining - pcDMARecvControlRecord.ELCNT = 1; // frame is 1 element - pcDMARecvControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE;// block is 8 frames - pcDMARecvControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte - pcDMARecvControlRecord.WRSIZE = ACCESS_8_BIT; // - pcDMARecvControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer - pcDMARecvControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed - pcDMARecvControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment - pcDMARecvControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off - pcDMARecvControlRecord.ELDOFFSET = 0; // # of bytes to advance at destination memory after each element - pcDMARecvControlRecord.ELSOFFSET = 0; // not used - pcDMARecvControlRecord.FRDOFFSET = 0; // # of bytes to advance at destination memory after each frame - pcDMARecvControlRecord.FRSOFFSET = 0; // not used + // TODO - remove this test code that sends a packet +// dmaSetCtrlPacket( DMA_CH3, pcDMAXmitControlRecord ); +// dmaSetChEnable( DMA_CH3, DMA_HW ); +// sciREG->SETINT = SCI_DMA_TRANSMIT_INT; } /************************************************************************* @@ -174,14 +136,14 @@ *************************************************************************/ void execSystemCommTx( void ) { - // TODO - check to see if CAN transmitter is idle first - if ( 1 ) // for now, assume it's idle + // if CAN transmitter is idle, start transmitting any pending packets + if ( FALSE == CAN_TX_BUSY() ) { transmitNextCANPacket(); } - // TODO - check to see if UART transmitter is idle first - if ( 1 ) // for now, assume it's idle + // if UART transmitter is idle, start transmitting any pending packets + if ( FALSE == SCI1_TX_IN_PROGRESS() ) { transmitNextUARTPacket(); } @@ -219,11 +181,19 @@ // message interrupt is for a transmit message box? if ( TRUE == isCANBoxForXmit( srcCANBox ) ) { - handleCANXmitCompleteInt(); + transmitNextCANPacket(); } else if ( TRUE == isCANBoxForRecv( srcCANBox ) ) { - handleCANPacketReceivedInt( srcCANBox ); + U08 data[CAN_MESSAGE_CARGO_SIZE]; + + // get CAN packet received on given CAN message box + if ( FALSE != canIsRxMessageArrived( canREG1, srcCANBox ) ) + { + canGetData( canREG1, srcCANBox, data ); + // add CAN packet to appropriate comm buffer based on the message box it came in on (s/b same #) + addToCommBuffer( srcCANBox, data, CAN_MESSAGE_CARGO_SIZE ); + } } else { @@ -232,23 +202,106 @@ } } +/************************************************************************* + * @brief handleUARTMsgRecvPacketInterrupt + * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive \n + * packet completed interrupt. + * @details + * Inputs : none + * Outputs : none + * @param none + * @return none + *************************************************************************/ void handleUARTMsgRecvPacketInterrupt( void ) { // buffer received packet - addToCommBuffer( COMM_BUFFER_IN_DBG, pcRecvPacket, PC_MESSAGE_PACKET_SIZE ); + addToCommBuffer( COMM_BUFFER_IN_UART_PC, pcRecvPacket, PC_MESSAGE_PACKET_SIZE ); // prepare to receive next packet dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord ); dmaSetChEnable( DMA_CH1, DMA_HW ); sciREG->SETINT = (uint32)((uint32)1U << 18U); /* Rx DMA All */ sciREG->SETINT = (uint32)((uint32)1U << 17U); /* Rx DMA */ } +/************************************************************************* + * @brief handleUARTMsgXmitPacketInterrupt + * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit \n + * packet completed interrupt. + * @details + * Inputs : none + * Outputs : none + * @param none + * @return none + *************************************************************************/ void handleUARTMsgXmitPacketInterrupt( void ) { - handleUARTXmitCompleteInt(); + transmitNextUARTPacket(); } +/************************************************************************* + * @brief initUARTAndDMA + * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA \n + * to go with it for PC communication. + * @details + * Inputs : none + * Outputs : SCI1 and DMA initialized + * @param none + * @return none + *************************************************************************/ +static void initUARTAndDMA( void ) +{ + // Enable DMA block transfer complete interrupts + dmaEnableInterrupt( DMA_CH1, BTC ); + dmaEnableInterrupt( DMA_CH3, BTC ); + // assign DMA channels to h/w DMA requests + dmaReqAssign( DMA_CH1, SCI1_RECEIVE_DMA_REQUEST ); + dmaReqAssign( DMA_CH3, SCI1_TRANSMIT_DMA_REQUEST ); + // set DMA channel priorities + dmaSetPriority( DMA_CH1, HIGHPRIORITY ); + dmaSetPriority( DMA_CH3, LOWPRIORITY ); + // initialize PC DMA Transmit Control Record + pcDMAXmitControlRecord.PORTASGN = 4; // port B (only choice per datasheet) + pcDMAXmitControlRecord.DADD = (U32)(&(sciREG->TD)); // dest. is SCI2 xmit register + pcDMAXmitControlRecord.SADD = (U32)pcXmitPacket; // source + pcDMAXmitControlRecord.CHCTRL = 0; // no chaining + pcDMAXmitControlRecord.ELCNT = 1; // frame is 1 element + pcDMAXmitControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames + pcDMAXmitControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte + pcDMAXmitControlRecord.WRSIZE = ACCESS_8_BIT; // + pcDMAXmitControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer + pcDMAXmitControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed + pcDMAXmitControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment + pcDMAXmitControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off + pcDMAXmitControlRecord.ELSOFFSET = 0; // not used + pcDMAXmitControlRecord.ELDOFFSET = 0; // not used + pcDMAXmitControlRecord.FRSOFFSET = 0; // not used + pcDMAXmitControlRecord.FRDOFFSET = 0; // not used + + // initialize PC DMA Receipt Control Record + pcDMARecvControlRecord.PORTASGN = 4; // port B (only choice per datasheet) + pcDMARecvControlRecord.SADD = (U32)(&(sciREG->RD)); // source is SCI2 recv register + pcDMARecvControlRecord.DADD = (U32)pcRecvPacket; // transfer destination address + pcDMARecvControlRecord.CHCTRL = 0; // no chaining + pcDMARecvControlRecord.ELCNT = 1; // frame is 1 element + pcDMARecvControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames + pcDMARecvControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte + pcDMARecvControlRecord.WRSIZE = ACCESS_8_BIT; // + pcDMARecvControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer + pcDMARecvControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed + pcDMARecvControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment + pcDMARecvControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off + pcDMARecvControlRecord.ELDOFFSET = 0; // not used + pcDMARecvControlRecord.ELSOFFSET = 0; // not used + pcDMARecvControlRecord.FRDOFFSET = 0; // not used + pcDMARecvControlRecord.FRSOFFSET = 0; // not used + + // initiate UART packet receiving readiness via DMA + dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord ); + dmaSetChEnable( DMA_CH1, DMA_HW ); + sciREG->SETINT = SCI_DMA_RECEIVE_INT; +} + /************************************************************************* * @brief isCANBoxForXmit * The isCANBoxForXmit function determines whether a given CAN message box \n @@ -281,7 +334,7 @@ * The isCANBoxForRecv function determines whether a given CAN message box \n * is configured for receiving. * @details - * Inputs : CAN_IN_BUFFERS[] + * Inputs : MSG_IN_BUFFERS[] * Outputs : none * @param srcCANBox : which CAN message box to check * @return TRUE if the given CAN message box is configured for receiving, FALSE if not. @@ -293,7 +346,7 @@ for ( i = 0; i < NUM_OF_CAN_IN_BUFFERS; i++ ) { - if ( CAN_IN_BUFFERS[i] == srcCANBox ) + if ( MSG_IN_BUFFERS[i] == srcCANBox ) { result = TRUE; break; @@ -310,28 +363,6 @@ /************************************************************************* - * @brief handleCANXmitCompleteInt - * The handleCANXmitCompleteInt function handles a CAN Tx complete interrupt. \n - * A search for the next highest priority pack to transmit is made and a \n - * new packet transmit is initiated on the appropriate CAN message box if \n - * a CAN packet is found. - * @details - * Inputs : Comm buffers - * Outputs : new CAN packet transmission is initiated - * @param none - * @return none - *************************************************************************/ -static void handleCANXmitCompleteInt( void ) -{ - transmitNextCANPacket(); -} - -static void handleUARTXmitCompleteInt( void ) -{ - transmitNextUARTPacket(); -} - -/************************************************************************* * @brief findNextHighestPriorityCANPacketToTransmit * The findNextHighestPriorityCANPacketToTransmit function gets the next \n * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. \n @@ -401,8 +432,7 @@ *************************************************************************/ static void transmitNextUARTPacket( void ) { - U08 data[PC_MESSAGE_PACKET_SIZE]; - U32 dataSize = getFromCommBuffer( COMM_BUFFER_OUT_DBG, data, PC_MESSAGE_PACKET_SIZE ); + U32 dataSize = getFromCommBuffer( COMM_BUFFER_OUT_UART_PC, pcXmitPacket, PC_MESSAGE_PACKET_SIZE ); // if there's another UART packet to send, send it if ( dataSize == PC_MESSAGE_PACKET_SIZE ) @@ -420,30 +450,6 @@ /************************************************************************* - * @brief handleCANPacketReceivedInt - * The handleCANPacketReceivedInt function handles a CAN Rx interrupt. \n - * A new CAN packet is added to the appropriate comm buffer based on the \n - * message box that it came in on. - * @details - * Inputs : none - * Outputs : new CAN packet added to associated comm buffer - * @param srcCANBox : CAN message box that the packet arrived in - * @return none - *************************************************************************/ -static void handleCANPacketReceivedInt( CAN_MESSAGE_BOX_T srcCANBox ) -{ - U08 data[CAN_MESSAGE_CARGO_SIZE]; - - // get CAN packet received on given CAN message box - if ( FALSE != canIsRxMessageArrived( canREG1, srcCANBox ) ) - { - canGetData( canREG1, srcCANBox, data ); - // add CAN packet to appropriate comm buffer based on the message box it came in on (s/b same #) - addToCommBuffer( srcCANBox, data, CAN_MESSAGE_CARGO_SIZE ); - } -} - -/************************************************************************* * @brief processIncomingData * The processIncomingData function parses out messages from the Input \n * Comm Buffers and adds them to the Received Message Queue. @@ -458,8 +464,8 @@ U08 data[sizeof(MESSAGE_WRAPPER_T)+1]; U32 i; - // queue any received CAN messages - for ( i = 0; i < NUM_OF_CAN_IN_BUFFERS; i++ ) + // queue any received messages + for ( i = 0; i < NUM_OF_MSG_IN_BUFFERS; i++ ) { BOOL messagesInBuffer = TRUE; // assume true at first to get into while loop @@ -470,19 +476,19 @@ // assume false so we don't get stuck in loop - only set to true if we find another complete message in buffer messagesInBuffer = FALSE; - // since messages can have CAN padding left unconsumed by last get, get padding out of buffer - consumeBufferPaddingBeforeSync( CAN_IN_BUFFERS[i] ); + // since messages can have 8-byte alignment padding left unconsumed by last get, get padding out of buffer + consumeBufferPaddingBeforeSync( MSG_IN_BUFFERS[i] ); // do we have enough bytes in buffer for smallest message? - numOfBytesInBuffer = numberOfBytesInCommBuffer( CAN_IN_BUFFERS[i] ); + numOfBytesInBuffer = numberOfBytesInCommBuffer( MSG_IN_BUFFERS[i] ); if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE ) { // peek at minimum of all bytes available or max message size (+1 for sync byte) - U32 bytesPeeked = peekFromCommBuffer( CAN_IN_BUFFERS[i], data, MIN(numOfBytesInBuffer,sizeof(MESSAGE_WRAPPER_T)+1) ); + U32 bytesPeeked = peekFromCommBuffer( MSG_IN_BUFFERS[i], data, MIN(numOfBytesInBuffer,sizeof(MESSAGE_WRAPPER_T)+1) ); U32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); if ( msgSize > 0 ) { // consume message (+sync byte) - msgSize = getFromCommBuffer( CAN_IN_BUFFERS[i], data, msgSize+1 ); + msgSize = getFromCommBuffer( MSG_IN_BUFFERS[i], data, msgSize+1 ); // if message data is at least minimum size, convert received message data to a message and add to message queue if ( msgSize > MESSAGE_OVERHEAD_SIZE ) { @@ -501,14 +507,12 @@ // copy CRC portion of message data to the new message rcvMsg.crc = *dataPtr; // add new message to queue for later processing - addToMsgQueue( MSG_Q_IN_CAN, &rcvMsg ); + addToMsgQueue( MSG_Q_IN, &rcvMsg ); } // message is at least as large as minimum size } // looks like there is a complete message in the comm buffer } // enough data left in comm buffer to possibly be a complete message } // while loop to get all complete messages for each comm buffer } // for loop to check all comm buffers for messages - - // TODO - queue any received UART messages } /************************************************************************* @@ -604,7 +608,7 @@ while ( TRUE == isThereMsgRcvd ) { // see if any messages received - isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN_CAN, &message ); + isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN, &message ); if ( TRUE == isThereMsgRcvd ) { // TODO - check CRC before processing a message @@ -633,7 +637,9 @@ *************************************************************************/ static void processReceivedMessage( MESSAGE_T *message ) { - switch ( message->hdr.msgID ) + U16 msgID = message->hdr.msgID; + + switch ( msgID ) { case MSG_ID_OFF_BUTTON_PRESS: handleOffButtonConfirmMsgFromUI( message ); @@ -642,8 +648,33 @@ #endif break; + + + case MSG_ID_TESTER_LOGIN_REQUEST: + handleTesterLogInRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; } + + // handle any test messages if tester has logged in successfully + if ( ( msgID > MSG_ID_FIRST_TESTER_MESSAGE ) && ( TRUE == isTestingActivated() ) ) + { + switch ( msgID ) + { + case MSG_ID_OFF_BUTTON_STATE_OVERRIDE: + handleTestOffButtonStateOverrideRequest( message ); + break; + + case MSG_ID_STOP_BUTTON_STATE_OVERRIDE: + handleTestStopButtonStateOverrideRequest( message ); + break; + + default: + // TODO - unrecognized message ID received - ignore + break; + } + } } Index: App/Services/SystemCommMessages.c =================================================================== diff -u -r3323966fe741edbb36dffc78317ccf06ed93a68e -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 3323966fe741edbb36dffc78317ccf06ed93a68e) +++ App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -16,10 +16,10 @@ * **************************************************************************/ -#include #include // for memcpy() #include "Common.h" +#include "Buttons.h" #include "MsgQueues.h" #include "SystemCommMessages.h" #include "SystemComm.h" @@ -33,10 +33,18 @@ U08 confirmed; // 1 = confirmed, 0 = rejected/timed out } OFF_BUTTON_MESSAGE_FROM_UI_CARGO_T; +typedef struct +{ + U08 reset; + U08 button_state; +} BUTTON_STATE_OVERRIDE_CARGO_T; + #pragma pack(pop) // ********** private data ********** +static BOOL testerLoggedIn = FALSE; + // ********** private function prototypes ********** static U32 serializeMessage( MESSAGE_T msg, U08 *data ); @@ -106,7 +114,6 @@ MESSAGE_T msg; U32 msgSize; U08 data[sizeof(MESSAGE_WRAPPER_T)+1+CAN_MESSAGE_CARGO_SIZE]; // must hold full (wrapped) message + sync + any CAN padding - U08 *dataPtr = data; // create a message record blankMessage( &msg ); @@ -117,7 +124,7 @@ msgSize = serializeMessage( msg, data ); // add serialized message data to appropriate comm buffer - result = addToCommBuffer( COMM_BUFFER_OUT_CAN_HD_2_UI, dataPtr, msgSize ); + result = addToCommBuffer( COMM_BUFFER_OUT_CAN_HD_2_UI, data, msgSize ); return result; } @@ -140,3 +147,206 @@ userConfirmOffButton( cargo.confirmed ); } + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/************************************************************************* + * @brief handleTesterLogInRequest + * The handleTesterLogInRequest function handles a request to login as a \n + * tester. + * @details + * Inputs : none + * Outputs : message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTesterLogInRequest( MESSAGE_T *message ) +{ + // verify pass code + // TODO - placeholder - how do we want to authenticate tester? + if ( ( 3 == message->hdr.cargoLen ) && ( 0x31 == message->cargo[0] ) && ( 0x32 == message->cargo[1] ) && ( 0x33 == message->cargo[2] ) ) + { + testerLoggedIn = TRUE; + } + else + { + testerLoggedIn = FALSE; + } + // respond to would be tester + sendTesterLogInResponse(); +} + +/************************************************************************* + * @brief sendTesterLogInResponse + * The sendTesterLogInResponse function constructs a tester login response \n + * msg and queues the msg for transmit on the appropriate UART channel. + * @details + * Inputs : none + * Outputs : Off button msg constructed and queued. + * @param none + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTesterLogInResponse( void ) +{ + BOOL result; + MESSAGE_T msg; + U32 msgSize; + U08 data[sizeof(MESSAGE_WRAPPER_T)+1+1+CAN_MESSAGE_CARGO_SIZE]; // must hold full (wrapped) message + sync + any CAN padding + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_TESTER_LOGIN_REQUEST; + msg.hdr.cargoLen = 1; + msg.cargo[0] = (U08)testerLoggedIn; + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) + msgSize = serializeMessage( msg, data ); + + // add serialized message data to appropriate comm buffer + result = addToCommBuffer( COMM_BUFFER_OUT_UART_PC, data, msgSize ); + + return result; +} + +/************************************************************************* + * @brief isTestingActivated + * The isTestingActivated function determines whether a tester has successfully \n + * logged in to activate testing functionality. + * @details + * Inputs : testerLoggedIn + * Outputs : none + * @param none + * @return TRUE if a tester has logged in to activate testing, FALSE if not + *************************************************************************/ +BOOL isTestingActivated( void ) +{ + return testerLoggedIn; +} + +/************************************************************************* + * @brief handleTestOffButtonStateOverrideRequest + * The handleTestOffButtonStateOverrideRequest function handles a request to \n + * override the state of the off button. + * @details + * Inputs : none + * Outputs : message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestOffButtonStateOverrideRequest( MESSAGE_T *message ) +{ + BUTTON_STATE_OVERRIDE_CARGO_T cargo; + BOOL result; + + memcpy( &cargo, message->cargo, sizeof(BUTTON_STATE_OVERRIDE_CARGO_T) ); + + if ( FALSE == (BOOL)(cargo.reset) ) + { + result = testSetOffButtonStateOverride( (BUTTON_STATE_T)(cargo.button_state) ); + } + else + { + result = testResetOffButtonStateOverride(); + } + // respond to request + sendTestOffButtonStateOverrideResponse( result ); +} + +/************************************************************************* + * @brief sendTestOffButtonStateOverrideResponse + * The sendTestOffButtonStateOverrideResponse function constructs an off \n + * button override response msg and queues the msg for transmit on the \n + * appropriate UART channel. + * @details + * Inputs : none + * Outputs : Off button override response msg constructed and queued. + * @param ack : TRUE if override successful, FALSE if not + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTestOffButtonStateOverrideResponse( BOOL ack ) +{ + BOOL result; + MESSAGE_T msg; + U32 msgSize; + U08 data[sizeof(MESSAGE_WRAPPER_T)+1+1+CAN_MESSAGE_CARGO_SIZE]; // must hold full (wrapped) message + sync + any CAN padding + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_OFF_BUTTON_STATE_OVERRIDE; + msg.hdr.cargoLen = 1; + msg.cargo[0] = (U08)ack; + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) + msgSize = serializeMessage( msg, data ); + + // add serialized message data to appropriate comm buffer + result = addToCommBuffer( COMM_BUFFER_OUT_UART_PC, data, msgSize ); + + return result; +} + +/************************************************************************* + * @brief handleTestStopButtonStateOverrideRequest + * The handleTestStopButtonStateOverrideRequest function handles a request to \n + * override the stop button state. + * @details + * Inputs : none + * Outputs : message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestStopButtonStateOverrideRequest( MESSAGE_T *message ) +{ + BUTTON_STATE_OVERRIDE_CARGO_T cargo; + BOOL result; + + memcpy( &cargo, message->cargo, sizeof(BUTTON_STATE_OVERRIDE_CARGO_T) ); + + if ( FALSE == (BOOL)(cargo.reset) ) + { + result = testSetStopButtonStateOverride( (BUTTON_STATE_T)(cargo.button_state) ); + } + else + { + result = testResetStopButtonStateOverride(); + } + // respond to request + sendTestStopButtonStateOverrideResponse( result ); +} + +/************************************************************************* + * @brief sendTestStopButtonStateOverrideResponse + * The sendTestStopButtonStateOverrideResponse function constructs a stop \n + * button override response msg and queues the msg for transmit on the \n + * appropriate UART channel. + * @details + * Inputs : none + * Outputs : stop button override response msg constructed and queued. + * @param ack : TRUE if override successful, FALSE if not + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTestStopButtonStateOverrideResponse( BOOL ack ) +{ + BOOL result; + MESSAGE_T msg; + U32 msgSize; + U08 data[sizeof(MESSAGE_WRAPPER_T)+1+1+CAN_MESSAGE_CARGO_SIZE]; // must hold full (wrapped) message + sync + any CAN padding + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_STOP_BUTTON_STATE_OVERRIDE; + msg.hdr.cargoLen = 1; + msg.cargo[0] = (U08)ack; + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) + msgSize = serializeMessage( msg, data ); + + // add serialized message data to appropriate comm buffer + result = addToCommBuffer( COMM_BUFFER_OUT_UART_PC, data, msgSize ); + + return result; +} + Index: App/Services/SystemCommMessages.h =================================================================== diff -u -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) +++ App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -26,6 +26,10 @@ { MSG_ID_UNUSED = 0, MSG_ID_OFF_BUTTON_PRESS, + MSG_ID_FIRST_TESTER_MESSAGE = 8000, + MSG_ID_TESTER_LOGIN_REQUEST = MSG_ID_FIRST_TESTER_MESSAGE, + MSG_ID_OFF_BUTTON_STATE_OVERRIDE, + MSG_ID_STOP_BUTTON_STATE_OVERRIDE, NUM_OF_MSG_IDS } MSG_ID_T; @@ -35,4 +39,19 @@ BOOL sendOffButtonMsgToUI( void ); void handleOffButtonConfirmMsgFromUI( MESSAGE_T *message ); +// *********** public test support message functions ********** + +// MSG_TESTER_LOG_IN +void handleTesterLogInRequest( MESSAGE_T *message ); +BOOL sendTesterLogInResponse( void ); +BOOL isTestingActivated( void ); + +// MSG_ID_OFF_BUTTON_STATE_OVERRIDE +void handleTestOffButtonStateOverrideRequest( MESSAGE_T *message ); +BOOL sendTestOffButtonStateOverrideResponse( BOOL ack ); + +// MSG_ID_STOP_BUTTON_STATE_OVERRIDE +void handleTestStopButtonStateOverrideRequest( MESSAGE_T *message ); +BOOL sendTestStopButtonStateOverrideResponse( BOOL ack ); + #endif Index: Debug/ccsObjs.opt =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- Debug/ccsObjs.opt (.../ccsObjs.opt) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ Debug/ccsObjs.opt (.../ccsObjs.opt) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -1 +1 @@ -"./irqDispatch_a.obj" "./irqDispatch_c.obj" "./App/Controllers/AlarmLamp.obj" "./App/Controllers/Buttons.obj" "./App/Drivers/CPLD.obj" "./App/Drivers/SafetyShutdown.obj" "./App/Modes/ModeFault.obj" "./App/Modes/ModeInitPOST.obj" "./App/Modes/ModeOpParams.obj" "./App/Modes/ModePostTreat.obj" "./App/Modes/ModePreTreat.obj" "./App/Modes/ModePrescription.obj" "./App/Modes/ModeService.obj" "./App/Modes/ModeStandby.obj" "./App/Modes/ModeTreatment.obj" "./App/Modes/OperationModes.obj" "./App/Services/CommBuffers.obj" "./App/Services/FPGA.obj" "./App/Services/MsgQueues.obj" "./App/Services/SystemComm.obj" "./App/Services/SystemCommMessages.obj" "./App/Services/Timers.obj" "./App/Services/WatchdogMgmt.obj" "./App/Tasks/TaskBG.obj" "./App/Tasks/TaskGeneral.obj" "./App/Tasks/TaskPriority.obj" "./App/Tasks/TaskTimer.obj" "./source/can.obj" "./source/dabort.obj" "./source/errata_SSWF021_45.obj" "./source/esm.obj" "./source/gio.obj" "./source/lin.obj" "./source/mibspi.obj" "./source/notification.obj" "./source/pinmux.obj" "./source/rti.obj" "./source/sci.obj" "./source/sys_core.obj" "./source/sys_dma.obj" "./source/sys_intvecs.obj" "./source/sys_main.obj" "./source/sys_mpu.obj" "./source/sys_pcr.obj" "./source/sys_phantom.obj" "./source/sys_pmm.obj" "./source/sys_pmu.obj" "./source/sys_selftest.obj" "./source/sys_startup.obj" "./source/sys_vim.obj" "./source/system.obj" "../source/sys_link.cmd" -lrtsv7R4_T_le_v3D16_eabi.lib \ No newline at end of file +"./irqDispatch_a.obj" "./irqDispatch_c.obj" "./App/Controllers/AlarmLamp.obj" "./App/Controllers/Buttons.obj" "./App/Drivers/CPLD.obj" "./App/Drivers/SafetyShutdown.obj" "./App/Modes/ModeFault.obj" "./App/Modes/ModeInitPOST.obj" "./App/Modes/ModeOpParams.obj" "./App/Modes/ModePostTreat.obj" "./App/Modes/ModePreTreat.obj" "./App/Modes/ModePrescription.obj" "./App/Modes/ModeService.obj" "./App/Modes/ModeStandby.obj" "./App/Modes/ModeTreatment.obj" "./App/Modes/OperationModes.obj" "./App/Services/CommBuffers.obj" "./App/Services/CommInterrupts.obj" "./App/Services/FPGA.obj" "./App/Services/MsgQueues.obj" "./App/Services/SystemComm.obj" "./App/Services/SystemCommMessages.obj" "./App/Services/Timers.obj" "./App/Services/WatchdogMgmt.obj" "./App/Tasks/TaskBG.obj" "./App/Tasks/TaskGeneral.obj" "./App/Tasks/TaskPriority.obj" "./App/Tasks/TaskTimer.obj" "./source/can.obj" "./source/dabort.obj" "./source/errata_SSWF021_45.obj" "./source/esm.obj" "./source/gio.obj" "./source/lin.obj" "./source/mibspi.obj" "./source/notification.obj" "./source/pinmux.obj" "./source/rti.obj" "./source/sci.obj" "./source/sys_core.obj" "./source/sys_dma.obj" "./source/sys_intvecs.obj" "./source/sys_main.obj" "./source/sys_mpu.obj" "./source/sys_pcr.obj" "./source/sys_phantom.obj" "./source/sys_pmm.obj" "./source/sys_pmu.obj" "./source/sys_selftest.obj" "./source/sys_startup.obj" "./source/sys_vim.obj" "./source/system.obj" "../source/sys_link.cmd" -lrtsv7R4_T_le_v3D16_eabi.lib \ No newline at end of file Index: Debug/makefile =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- Debug/makefile (.../makefile) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ Debug/makefile (.../makefile) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -25,6 +25,7 @@ "./App/Modes/ModeTreatment.obj" \ "./App/Modes/OperationModes.obj" \ "./App/Services/CommBuffers.obj" \ +"./App/Services/CommInterrupts.obj" \ "./App/Services/FPGA.obj" \ "./App/Services/MsgQueues.obj" \ "./App/Services/SystemComm.obj" \ @@ -214,10 +215,10 @@ # Other Targets clean: -$(RM) $(BIN_OUTPUTS__QUOTED)$(EXE_OUTPUTS__QUOTED) - -$(RM) "irqDispatch_a.obj" "irqDispatch_c.obj" "App/Controllers/AlarmLamp.obj" "App/Controllers/Buttons.obj" "App/Drivers/CPLD.obj" "App/Drivers/SafetyShutdown.obj" "App/Modes/ModeFault.obj" "App/Modes/ModeInitPOST.obj" "App/Modes/ModeOpParams.obj" "App/Modes/ModePostTreat.obj" "App/Modes/ModePreTreat.obj" "App/Modes/ModePrescription.obj" "App/Modes/ModeService.obj" "App/Modes/ModeStandby.obj" "App/Modes/ModeTreatment.obj" "App/Modes/OperationModes.obj" "App/Services/CommBuffers.obj" "App/Services/FPGA.obj" "App/Services/MsgQueues.obj" "App/Services/SystemComm.obj" "App/Services/SystemCommMessages.obj" "App/Services/Timers.obj" "App/Services/WatchdogMgmt.obj" "App/Tasks/TaskBG.obj" "App/Tasks/TaskGeneral.obj" "App/Tasks/TaskPriority.obj" "App/Tasks/TaskTimer.obj" "source/can.obj" "source/dabort.obj" "source/errata_SSWF021_45.obj" "source/esm.obj" "source/gio.obj" "source/lin.obj" "source/mibspi.obj" "source/notification.obj" "source/pinmux.obj" "source/rti.obj" "source/sci.obj" "source/sys_core.obj" - -$(RM) "source/sys_dma.obj" "source/sys_intvecs.obj" "source/sys_main.obj" "source/sys_mpu.obj" "source/sys_pcr.obj" "source/sys_phantom.obj" "source/sys_pmm.obj" "source/sys_pmu.obj" "source/sys_selftest.obj" "source/sys_startup.obj" "source/sys_vim.obj" "source/system.obj" - -$(RM) "irqDispatch_c.d" "App/Controllers/AlarmLamp.d" "App/Controllers/Buttons.d" "App/Drivers/CPLD.d" "App/Drivers/SafetyShutdown.d" "App/Modes/ModeFault.d" "App/Modes/ModeInitPOST.d" "App/Modes/ModeOpParams.d" "App/Modes/ModePostTreat.d" "App/Modes/ModePreTreat.d" "App/Modes/ModePrescription.d" "App/Modes/ModeService.d" "App/Modes/ModeStandby.d" "App/Modes/ModeTreatment.d" "App/Modes/OperationModes.d" "App/Services/CommBuffers.d" "App/Services/FPGA.d" "App/Services/MsgQueues.d" "App/Services/SystemComm.d" "App/Services/SystemCommMessages.d" "App/Services/Timers.d" "App/Services/WatchdogMgmt.d" "App/Tasks/TaskBG.d" "App/Tasks/TaskGeneral.d" "App/Tasks/TaskPriority.d" "App/Tasks/TaskTimer.d" "source/can.d" "source/errata_SSWF021_45.d" "source/esm.d" "source/gio.d" "source/lin.d" "source/mibspi.d" "source/notification.d" "source/pinmux.d" "source/rti.d" "source/sci.d" "source/sys_dma.d" "source/sys_main.d" "source/sys_pcr.d" "source/sys_phantom.d" "source/sys_pmm.d" "source/sys_selftest.d" "source/sys_startup.d" - -$(RM) "source/sys_vim.d" "source/system.d" + -$(RM) "irqDispatch_a.obj" "irqDispatch_c.obj" "App/Controllers/AlarmLamp.obj" "App/Controllers/Buttons.obj" "App/Drivers/CPLD.obj" "App/Drivers/SafetyShutdown.obj" "App/Modes/ModeFault.obj" "App/Modes/ModeInitPOST.obj" "App/Modes/ModeOpParams.obj" "App/Modes/ModePostTreat.obj" "App/Modes/ModePreTreat.obj" "App/Modes/ModePrescription.obj" "App/Modes/ModeService.obj" "App/Modes/ModeStandby.obj" "App/Modes/ModeTreatment.obj" "App/Modes/OperationModes.obj" "App/Services/CommBuffers.obj" "App/Services/CommInterrupts.obj" "App/Services/FPGA.obj" "App/Services/MsgQueues.obj" "App/Services/SystemComm.obj" "App/Services/SystemCommMessages.obj" "App/Services/Timers.obj" "App/Services/WatchdogMgmt.obj" "App/Tasks/TaskBG.obj" "App/Tasks/TaskGeneral.obj" "App/Tasks/TaskPriority.obj" "App/Tasks/TaskTimer.obj" "source/can.obj" "source/dabort.obj" "source/errata_SSWF021_45.obj" "source/esm.obj" "source/gio.obj" "source/lin.obj" "source/mibspi.obj" "source/notification.obj" "source/pinmux.obj" "source/rti.obj" + -$(RM) "source/sci.obj" "source/sys_core.obj" "source/sys_dma.obj" "source/sys_intvecs.obj" "source/sys_main.obj" "source/sys_mpu.obj" "source/sys_pcr.obj" "source/sys_phantom.obj" "source/sys_pmm.obj" "source/sys_pmu.obj" "source/sys_selftest.obj" "source/sys_startup.obj" "source/sys_vim.obj" "source/system.obj" + -$(RM) "irqDispatch_c.d" "App/Controllers/AlarmLamp.d" "App/Controllers/Buttons.d" "App/Drivers/CPLD.d" "App/Drivers/SafetyShutdown.d" "App/Modes/ModeFault.d" "App/Modes/ModeInitPOST.d" "App/Modes/ModeOpParams.d" "App/Modes/ModePostTreat.d" "App/Modes/ModePreTreat.d" "App/Modes/ModePrescription.d" "App/Modes/ModeService.d" "App/Modes/ModeStandby.d" "App/Modes/ModeTreatment.d" "App/Modes/OperationModes.d" "App/Services/CommBuffers.d" "App/Services/CommInterrupts.d" "App/Services/FPGA.d" "App/Services/MsgQueues.d" "App/Services/SystemComm.d" "App/Services/SystemCommMessages.d" "App/Services/Timers.d" "App/Services/WatchdogMgmt.d" "App/Tasks/TaskBG.d" "App/Tasks/TaskGeneral.d" "App/Tasks/TaskPriority.d" "App/Tasks/TaskTimer.d" "source/can.d" "source/errata_SSWF021_45.d" "source/esm.d" "source/gio.d" "source/lin.d" "source/mibspi.d" "source/notification.d" "source/pinmux.d" "source/rti.d" "source/sci.d" "source/sys_dma.d" "source/sys_main.d" "source/sys_pcr.d" "source/sys_phantom.d" "source/sys_pmm.d" + -$(RM) "source/sys_selftest.d" "source/sys_startup.d" "source/sys_vim.d" "source/system.d" -$(RM) "irqDispatch_a.d" "source/dabort.d" "source/sys_core.d" "source/sys_intvecs.d" "source/sys_mpu.d" "source/sys_pmu.d" -@echo 'Finished clean' -@echo ' ' Index: HD.dil =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- HD.dil (.../HD.dil) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ HD.dil (.../HD.dil) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -1,4 +1,4 @@ -# RM46L852PGE 10/21/19 18:51:54 +# RM46L852PGE 10/22/19 16:38:22 # ARCH=RM46L852PGE # @@ -183,7 +183,7 @@ DRIVER.SYSTEM.VAR.MIBSPI_ENABLE.VALUE=1 DRIVER.SYSTEM.VAR.ECLK_VCLK1_FREQ.VALUE=103.335 DRIVER.SYSTEM.VAR.CLKT_EXTERNAL_FREQ.VALUE=00.0 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SIZE_VALUE.VALUE=0x0A +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SIZE_VALUE.VALUE=0x0F DRIVER.SYSTEM.VAR.VIM_CHANNEL_125_NAME.VALUE=phantomInterrupt DRIVER.SYSTEM.VAR.VIM_CHANNEL_117_NAME.VALUE=phantomInterrupt DRIVER.SYSTEM.VAR.VIM_CHANNEL_110_MAPPING.VALUE=110 @@ -291,7 +291,7 @@ DRIVER.SYSTEM.VAR.EMIF_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.CAN1_ENABLE.VALUE=1 DRIVER.SYSTEM.VAR.CAN_ENABLE.VALUE=1 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_TYPE_VALUE.VALUE=0x0008 +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_TYPE_VALUE.VALUE=0x000C DRIVER.SYSTEM.VAR.VIM_CHANNEL_3_NAME.VALUE=rtiCompare1Interrupt DRIVER.SYSTEM.VAR.PMM_MEM_PD3_STATEVALUE.VALUE=0xA DRIVER.SYSTEM.VAR.CLKT_PLL1_OUTPUT_DIV.VALUE=2 @@ -361,7 +361,7 @@ DRIVER.SYSTEM.VAR.RAM_STACK_ABORT_LENGTH.VALUE=0x00000100 DRIVER.SYSTEM.VAR.FLASH_DATA_MAX_WAIT_STATES.VALUE=3 DRIVER.SYSTEM.VAR.FLASH_MODE.VALUE=PIPELINE -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SUB_7_DISABLE.VALUE=1 +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SUB_7_DISABLE.VALUE=0 DRIVER.SYSTEM.VAR.CORE_MPU_REGION_7_SUB_1_DISABLE.VALUE=0 DRIVER.SYSTEM.VAR.VIM_CHANNEL_61_INT_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.VIM_CHANNEL_61_INT_TYPE.VALUE=IRQ @@ -525,7 +525,7 @@ DRIVER.SYSTEM.VAR.VIM_CHANNEL_6_MAPPING.VALUE=6 DRIVER.SYSTEM.VAR.CLKT_PLL2_SPEADING_AMOUNT.VALUE=61 DRIVER.SYSTEM.VAR.CLKT_PLL2_SPEADING_RATE.VALUE=255 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_BASE_ADDRESS.VALUE=0x08001000 +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_BASE_ADDRESS.VALUE=0x08020000 DRIVER.SYSTEM.VAR.CORE_MPU_REGION_6_TYPE.VALUE=STRONGLYORDERED_SHAREABLE DRIVER.SYSTEM.VAR.VIM_CHANNEL_121_INT_TYPE.VALUE=IRQ DRIVER.SYSTEM.VAR.VIM_CHANNEL_113_INT_TYPE.VALUE=IRQ @@ -550,7 +550,7 @@ DRIVER.SYSTEM.VAR.VIM_CHANNEL_77_NAME.VALUE=EMACTxIntISR DRIVER.SYSTEM.VAR.VIM_CHANNEL_69_NAME.VALUE=phantomInterrupt DRIVER.SYSTEM.VAR.RAM_STACK_IRQ_LENGTH.VALUE=0x00000100 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SUB_6_DISABLE.VALUE=1 +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SUB_6_DISABLE.VALUE=0 DRIVER.SYSTEM.VAR.CORE_MPU_REGION_7_SUB_0_DISABLE.VALUE=0 DRIVER.SYSTEM.VAR.VIM_CHANNEL_2_INT_PRAGMA_ENABLE.VALUE=1 DRIVER.SYSTEM.VAR.CLKT_RTI2_POST_SOURCE.VALUE=VCLK @@ -629,7 +629,7 @@ DRIVER.SYSTEM.VAR.PBIST_ALGO_16.VALUE=0 DRIVER.SYSTEM.VAR.CLKT_VCLK2_DIVIDER.VALUE=1 DRIVER.SYSTEM.VAR.RAM_LINK_LENGTH.VALUE=0x0002eb00 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_END_ADDRESS.VALUE=0x080017ff +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_END_ADDRESS.VALUE=0x0802ffff DRIVER.SYSTEM.VAR.VIM_CHANNEL_30_INT_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.VIM_CHANNEL_22_INT_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.VIM_CHANNEL_14_INT_ENABLE.VALUE=0 @@ -731,8 +731,8 @@ DRIVER.SYSTEM.VAR.PMM_MEM_PD1_STATEVALUE.VALUE=0x5 DRIVER.SYSTEM.VAR.CORE_MPU_REGION_7_PERMISSION.VALUE=PRIV_RW_USER_RO_NOEXEC DRIVER.SYSTEM.VAR.CORE_MPU_REGION_12_ENABLE.VALUE=0 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SUB_5_DISABLE.VALUE=1 -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SIZE.VALUE=2_KB +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SUB_5_DISABLE.VALUE=0 +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_SIZE.VALUE=64_KB DRIVER.SYSTEM.VAR.VIM_CHANNEL_127_INT_PRAGMA_ENABLE.VALUE=1 DRIVER.SYSTEM.VAR.VIM_CHANNEL_119_INT_PRAGMA_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.VIM_CHANNEL_60_INT_TYPE.VALUE=IRQ @@ -947,7 +947,7 @@ DRIVER.SYSTEM.VAR.CORE_MPU_REGION_6_PERMISSION.VALUE=PRIV_RW_USER_RW_EXEC DRIVER.SYSTEM.VAR.CLKT_VCLK2_DOMAIN_ENABLE.VALUE=FALSE DRIVER.SYSTEM.VAR.FLASH_BANK_CONFIG_3.VALUE=SLEEP -DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_TYPE.VALUE=NORMAL_OINC_NONSHARED +DRIVER.SYSTEM.VAR.CORE_MPU_REGION_11_TYPE.VALUE=NORMAL_OINC_SHARED DRIVER.SYSTEM.VAR.CORE_MPU_REGION_8_SUB_2_DISABLE.VALUE=0 DRIVER.SYSTEM.VAR.CORE_MPU_REGION_3_END_ADDRESS.VALUE=0x0803ffff DRIVER.SYSTEM.VAR.CORE_MPU_REGION_1_SUB_0_DISABLE.VALUE=1 @@ -1673,18 +1673,18 @@ DRIVER.SCI.VAR.SCI_PORT_BIT2_PULL.VALUE=2 DRIVER.SCI.VAR.SCILIN_PORT_BIT1_DIR.VALUE=0 DRIVER.SCI.VAR.SCI_PORT_BIT0_DIR.VALUE=0 -DRIVER.SCI.VAR.SCI_ACTUALBAUDRATE.VALUE=922634 +DRIVER.SCI.VAR.SCI_ACTUALBAUDRATE.VALUE=115329 DRIVER.SCI.VAR.SCI_EVENPARITY.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT0_FUN.VALUE=0 -DRIVER.SCI.VAR.SCILIN_PORT_BIT2_DIR.VALUE=1 +DRIVER.SCI.VAR.SCILIN_PORT_BIT2_DIR.VALUE=0 DRIVER.SCI.VAR.SCILIN_RXINTLVL.VALUE=0 DRIVER.SCI.VAR.SCI_PORT_BIT1_DIR.VALUE=0 DRIVER.SCI.VAR.SCI_BASE_PORT.VALUE=0xFFF7E540 DRIVER.SCI.VAR.SCILIN_PRESCALE.VALUE=6 DRIVER.SCI.VAR.SCILIN_PORT_BIT0_PDR.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT1_FUN.VALUE=1 DRIVER.SCI.VAR.SCI_PORT_BIT0_FUN.VALUE=0 -DRIVER.SCI.VAR.SCI_PORT_BIT2_DIR.VALUE=1 +DRIVER.SCI.VAR.SCI_PORT_BIT2_DIR.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT1_PDR.VALUE=0 DRIVER.SCI.VAR.SCI_PORT_BIT0_PDR.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT2_FUN.VALUE=1 @@ -1713,7 +1713,7 @@ DRIVER.SCI.VAR.SCILIN_PARITYENA.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT1_DOUT.VALUE=0 DRIVER.SCI.VAR.SCI_PORT_BIT0_DOUT.VALUE=0 -DRIVER.SCI.VAR.SCI_BAUDRATE.VALUE=921600 +DRIVER.SCI.VAR.SCI_BAUDRATE.VALUE=115200 DRIVER.SCI.VAR.SCILIN_BREAKINTLVL.VALUE=0 DRIVER.SCI.VAR.SCI_WAKEINTLVL.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT0_PULDIS.VALUE=0 @@ -1734,9 +1734,9 @@ DRIVER.SCI.VAR.SCILIN_BASE.VALUE=0xFFF7E400 DRIVER.SCI.VAR.SCI_RXINTLVL.VALUE=0 DRIVER.SCI.VAR.SCILIN_FEINTENA.VALUE=1 -DRIVER.SCI.VAR.SCI_PRESCALE.VALUE=6 +DRIVER.SCI.VAR.SCI_PRESCALE.VALUE=55 DRIVER.SCI.VAR.SCILIN_OEINTLVL.VALUE=0 -DRIVER.SCI.VAR.SCILIN_TXINTENA.VALUE=1 +DRIVER.SCI.VAR.SCILIN_TXINTENA.VALUE=0 DRIVER.SCI.VAR.SCI_PORT_BIT2_PULDIS.VALUE=0 DRIVER.SCI.VAR.SCILIN_PORT_BIT1_PULL.VALUE=2 DRIVER.SCI.VAR.SCI_PORT_BIT0_PULL.VALUE=2 @@ -1749,7 +1749,7 @@ DRIVER.SCI.VAR.SCILIN_STOPBITS.VALUE=1 DRIVER.SCI.VAR.SCILIN_PORT_BIT2_PULL.VALUE=2 DRIVER.SCI.VAR.SCI_PORT_BIT1_PULL.VALUE=2 -DRIVER.SCI.VAR.SCILIN_RXINTENA.VALUE=1 +DRIVER.SCI.VAR.SCILIN_RXINTENA.VALUE=0 DRIVER.SCI.VAR.SCILIN_LENGTH.VALUE=8 DRIVER.SCI.VAR.SCILIN_FEINTLVL.VALUE=0 DRIVER.SCI.VAR.SCILIN_ACTUALBAUDRATE.VALUE=922634 Index: include/sci.h =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- include/sci.h (.../sci.h) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ include/sci.h (.../sci.h) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -138,9 +138,9 @@ |(uint32)((uint32)0U << 0U)) #define SCI_FORMAT_CONFIGVALUE (8U - 1U) -#define SCI_BRS_CONFIGVALUE (6U) +#define SCI_BRS_CONFIGVALUE (55U) #define SCI_PIO0_CONFIGVALUE ((uint32)((uint32)1U << 2U ) | (uint32)((uint32)1U << 1U)) -#define SCI_PIO1_CONFIGVALUE ((uint32)((uint32)1U << 2U ) | (uint32)((uint32)0U << 1U)) +#define SCI_PIO1_CONFIGVALUE ((uint32)((uint32)0U << 2U ) | (uint32)((uint32)0U << 1U)) #define SCI_PIO6_CONFIGVALUE ((uint32)((uint32)0U << 2U ) | (uint32)((uint32)0U << 1U)) #define SCI_PIO7_CONFIGVALUE ((uint32)((uint32)0U << 2U ) | (uint32)((uint32)0U << 1U)) #define SCI_PIO8_CONFIGVALUE ((uint32)((uint32)1U << 2U ) | (uint32)((uint32)1U << 1U)) @@ -168,14 +168,14 @@ #define SCILIN_SETINT_CONFIGVALUE ((uint32)((uint32)1U << 26U) \ |(uint32)((uint32)1U << 25U) \ |(uint32)((uint32)0U << 24U) \ - |(uint32)((uint32)1U << 9U) \ + |(uint32)((uint32)0U << 9U) \ |(uint32)((uint32)0U << 1U) \ |(uint32)((uint32)0U << 0U)) #define SCILIN_FORMAT_CONFIGVALUE (8U - 1U) #define SCILIN_BRS_CONFIGVALUE (6U) #define SCILIN_PIO0_CONFIGVALUE ((uint32)((uint32)1U << 2U) | (uint32)((uint32)1U << 1U)) -#define SCILIN_PIO1_CONFIGVALUE ((uint32)((uint32)1U << 2U) | (uint32)((uint32)0U << 1U)) +#define SCILIN_PIO1_CONFIGVALUE ((uint32)((uint32)0U << 2U) | (uint32)((uint32)0U << 1U)) #define SCILIN_PIO6_CONFIGVALUE ((uint32)((uint32)0U << 2U) | (uint32)((uint32)0U << 1U)) #define SCILIN_PIO7_CONFIGVALUE ((uint32)((uint32)0U << 2U) | (uint32)((uint32)0U << 1U)) #define SCILIN_PIO8_CONFIGVALUE ((uint32)((uint32)1U << 2U) | (uint32)((uint32)1U << 1U)) Index: source/sci.c =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- source/sci.c (.../sci.c) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ source/sci.c (.../sci.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -96,7 +96,7 @@ | (uint32)((uint32)1U << 1U); /* asynchronous timing mode */ /** - set baudrate */ - sciREG->BRS = 6U; /* baudrate */ + sciREG->BRS = 55U; /* baudrate */ /** - transmission length */ sciREG->FORMAT = 8U - 1U; /* length */ @@ -110,7 +110,7 @@ | (uint32)((uint32)0U << 1U); /* rx pin */ /** - set SCI pins output direction */ - sciREG->PIO1 = (uint32)((uint32)1U << 2U) /* tx pin */ + sciREG->PIO1 = (uint32)((uint32)0U << 2U) /* tx pin */ | (uint32)((uint32)0U << 1U); /* rx pin */ /** - set SCI pins open drain enable */ @@ -188,7 +188,7 @@ /** - set SCI pins output direction */ - scilinREG->PIO1 = (uint32)((uint32)1U << 2U) /* tx pin */ + scilinREG->PIO1 = (uint32)((uint32)0U << 2U) /* tx pin */ | (uint32)((uint32)0U << 1U); /* rx pin */ @@ -220,12 +220,12 @@ scilinREG->SETINT = (uint32)((uint32)1U << 26U) /* Framing error */ | (uint32)((uint32)1U << 25U) /* Overrun error */ | (uint32)((uint32)0U << 24U) /* Parity error */ - | (uint32)((uint32)1U << 9U) /* Receive */ + | (uint32)((uint32)0U << 9U) /* Receive */ | (uint32)((uint32)0U << 1U) /* Wakeup */ | (uint32)((uint32)0U); /* Break detect */ /** - initialize global transfer variables */ - g_sciTransfer_t[1U].mode = (uint32)1U << 8U; + g_sciTransfer_t[1U].mode = (uint32)0U << 8U; g_sciTransfer_t[1U].tx_length = 0U; g_sciTransfer_t[1U].rx_length = 0U; Index: source/sys_main.c =================================================================== diff -u -rcb47c5f896477ceae7597cb1a4191b3972e93f0d -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- source/sys_main.c (.../sys_main.c) (revision cb47c5f896477ceae7597cb1a4191b3972e93f0d) +++ source/sys_main.c (.../sys_main.c) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -127,6 +127,8 @@ canInit(); // CAN1 = CAN, re-purposing CAN2 and CAN3 Rx and Tx pins as GPIO sciInit(); // SCI1 used for PC serial interface, SCI2 used for FPGA serial interface dmaEnable(); // enable DMA +// sciEnableLoopback( sciREG, Digital_Lbk ); // TODO - for test only +// sciEnableLoopback( scilinREG, Digital_Lbk ); // TODO - for test only } /************************************************************************* @@ -184,58 +186,4 @@ _enable_IRQ(); } -void sciNotification(sciBASE_t *sci, uint32 flags) -{ - static U32 fErrorCnt = 0; - static U32 oErrorCnt = 0; - - if ( ( flags & SCI_FE_INT ) != 0 ) - { - fErrorCnt++; - } - if ( ( flags & SCI_OE_INT ) != 0 ) - { - oErrorCnt++; - } -} - -void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel) -{ - if ( inttype == BTC ) - { - switch ( channel ) - { - case DMA_CH0: - // clear DMA receipt - scilinREG->CLEARINT = (uint32)((uint32)1U << 17U); /* Rx DMA */ - scilinREG->CLEARINT = (uint32)((uint32)1U << 18U); /* Rx DMA All */ - break; - - case DMA_CH1: - // clear DMA receipt - sciREG->CLEARINT = (uint32)((uint32)1U << 17U); /* Rx DMA */ - sciREG->CLEARINT = (uint32)((uint32)1U << 18U); /* Rx DMA All */ - // handle received packet from PC - handleUARTMsgRecvPacketInterrupt(); - break; - - case DMA_CH2: - // clear DMA xmit - scilinREG->CLEARINT = (uint32)((uint32)1U << 16U); /* Tx DMA */ - break; - - case DMA_CH3: - // clear DMA xmit - sciREG->CLEARINT = (uint32)((uint32)1U << 16U); /* Tx DMA */ - // send next pending packet to PC (if any) - handleUARTMsgXmitPacketInterrupt(); - break; - - default: - // TODO - ignore? - break; - } - } -} - /* USER CODE END */ Index: source/sys_mpu.asm =================================================================== diff -u -r765d2c35118e202444e737c66c77faf9678cc87e -r38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9 --- source/sys_mpu.asm (.../sys_mpu.asm) (revision 765d2c35118e202444e737c66c77faf9678cc87e) +++ source/sys_mpu.asm (.../sys_mpu.asm) (revision 38ff7a6fbf82b86ab1bac3b7b24c4ea33d5419f9) @@ -164,10 +164,10 @@ mcr p15, #0, r0, c6, c2, #0 ldr r0, r11Base mcr p15, #0, r0, c6, c1, #0 - mov r0, #0x0008 + mov r0, #0x000C orr r0, r0, #0x1100 mcr p15, #0, r0, c6, c1, #4 - movw r0, #((1 << 15) + (1 << 14) + (1 << 13) + (0 << 12) + (0 << 11) + (0 << 10) + (0 << 9) + (0 << 8) + (0x0A << 1) + (0)) + movw r0, #((0 << 15) + (0 << 14) + (0 << 13) + (0 << 12) + (0 << 11) + (0 << 10) + (0 << 9) + (0 << 8) + (0x0F << 1) + (0)) mcr p15, #0, r0, c6, c1, #2 ; Setup region 12 mov r0, #11 @@ -203,7 +203,7 @@ r8Base .word 0xFC000000 r9Base .word 0xFE000000 r10Base .word 0xFF000000 -r11Base .word 0x08001000 +r11Base .word 0x08020000 r12Base .word 0x20000000 .endasmfunc