/************************************************************************** * * 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 SystemComm.c * * @date 08-Oct-2019 * @author S. Nash * * @brief SystemComm service module. Provides system message communication \n * functionality. Messages can be queued for transmission. Incoming messages \n * are processed. * **************************************************************************/ #include "can.h" #include "Common.h" #include "Buttons.h" #include "CommBuffers.h" #include "MsgQueues.h" #include "SystemComm.h" // ***************************** TEST CODE ****************************** // TODO - remove later #if 1 #include "CPLD.h" #endif // ************************** END TEST CODE ****************************** // ********** private definitions ********** #define MESSAGE_SYNC_BYTE 0xA5 #define CAN_MESSAGE_CARGO_SIZE 8 typedef enum Msg_IDs { MSG_ID_TEST = 0, MSG_ID_OFF_BUTTON_PRESS, NUM_OF_MSG_IDS } MSG_ID_T; // ********** private data ********** // ********** private function prototypes ********** static U32 serializeMessage( MESSAGE_T msg, U08 *data ); /************************************************************************* * @brief initSystemComm * The initSystemComm function initializes the SystemComm module. * @details * Inputs : none * Outputs : SystemComm module initialized. * @param none * @return none *************************************************************************/ void initSystemComm( void ) { } /************************************************************************* * @brief execSystemCommRx * The execSystemCommRx function manages received data from other sub-systems. * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ void execSystemCommRx( void ) { // TODO - this is ugly preliminary test code - nowhere near ready for code review BOOL isThereMsgRcvd; U08 data[sizeof(MESSAGE_WRAPPER_T)]; MESSAGE_WRAPPER_T msg; // queue any received CAN messages if ( FALSE != canIsRxMessageArrived( canREG1, canMESSAGE_BOX2 ) ) { MESSAGE_WRAPPER_T rcvMsg; U08 *dataPtr = data; canGetData( canREG1, canMESSAGE_BOX2, data ); blankMessageInWrapper( &rcvMsg ); memcpy( &(rcvMsg.msg.hdr), dataPtr, sizeof(MESSAGE_HEADER_T) ); dataPtr += sizeof(MESSAGE_HEADER_T); memcpy( &(rcvMsg.msg.cargo), dataPtr, rcvMsg.msg.hdr.cargoLen ); dataPtr += rcvMsg.msg.hdr.cargoLen; rcvMsg.crc = *dataPtr; addToMsgQueue( MSG_Q_IN_CAN_UI_2_HD, &rcvMsg ); } // see if any messages received isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN_CAN_UI_2_HD, &msg ); if ( TRUE == isThereMsgRcvd ) { switch ( msg.msg.hdr.msgID ) { case MSG_ID_OFF_BUTTON_PRESS: userConfirmOffButton( msg.msg.cargo[0] ); // ***************************** TEST CODE ****************************** // TODO - remove later #if 1 setUserLED( TRUE ); #endif // ************************** END TEST CODE ****************************** break; default: break; } } } /************************************************************************* * @brief execSystemCommTx * The execSystemCommTx function manages data to be transmitted to other \n * sub-systems. * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ void execSystemCommTx( void ) { // TODO - this is ugly preliminary test code - nowhere near ready for code review U08 data[sizeof(MESSAGE_WRAPPER_T)]; U32 dataSize; // actually transmit any pending messages dataSize = getFromCommBuffer( COMM_BUFFER_OUT_CAN_HD_2_UI, data, CAN_MESSAGE_CARGO_SIZE ); if ( dataSize > 0 ) { canTransmit( canREG1, canMESSAGE_BOX1, data ); } } /************************************************************************* * @brief serializeMessage * The serializeMessage function serializes a given message into a given \n * array of bytes. A sync byte is inserted at the beginning of the message \n * and an 8-bit CRC is appended to the end of the message. The given array \n * must be large enough to hold the message + 1 sync byte and 1 CRC byte and \n * up to 7 CAN padding bytes. * @details * Inputs : none * Outputs : given data array populated with serialized message data. * @param msg : message to serialize * @param data : byte array to populate with message data * @return size (in bytes) of serialized message populated in given data array. *************************************************************************/ static U32 serializeMessage( MESSAGE_T msg, U08 *data ) { U32 msgSize = 0; U32 sizeMod, sizePad; U32 i; // prefix data with message sync byte //data[msgSize++] = MESSAGE_SYNC_BYTE; // serialize message header data memcpy( &data[msgSize], &(msg.hdr), sizeof(MESSAGE_HEADER_T) ); msgSize += sizeof(MESSAGE_HEADER_T); // serialize message cargo (only used bytes per cargoLen field) memcpy( &data[msgSize], &(msg.cargo), msg.hdr.cargoLen ); msgSize += msg.hdr.cargoLen; // TODO - calculate 8-bit CRC data[msgSize++] = 0; // TODO - s/b 8-bit CRC when calc is available // pad with zero bytes to get length a multiple of CAN_MESSAGE_CARGO_SIZE (8) sizeMod = msgSize % CAN_MESSAGE_CARGO_SIZE; sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_CARGO_SIZE - sizeMod ); for ( i = 0; i < sizePad; i++ ) { data[msgSize++] = 0; } return msgSize; } /************************************************************************* *************** SUITE OFF SEND MESSAGE FUNCTIONS BELOW ******************* *************************************************************************/ /************************************************************************* * @brief sendOffButtonMsgToUI * The sendOffButtonMsgToUI function constructs an off button msg to the UI \n * and queues the msg for transmit on the appropriate CAN 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 sendOffButtonMsgToUI( void ) { BOOL result; 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 ); msg.hdr.msgID = MSG_ID_OFF_BUTTON_PRESS; msg.hdr.cargoLen = 0; // 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_CAN_HD_2_UI, dataPtr, msgSize ); return result; }