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; + } + } }