#include // For memcpy #include "CommBuffers.h" #include "Utilities.h" /** * @addtogroup CommBuffers * @{ */ // ********** private definitions ********** #define MAX_NUM_OF_CAN_BYTES ( SW_UPDATE_FLASH_BUFFER_SIZE + CAN_MESSAGE_PAYLOAD_SIZE ) ///< Maximum number of CAN bytes. // ********** private data ********** /// Software update buffer structure typedef struct { U32 SWUpdateFrameCount; ///< Software update frame count. U08 SWUpdateBuffer[ MAX_NUM_OF_CAN_BYTES ]; ///< Software update buffer. } SW_UPDATE_BUFFER_T; static SW_UPDATE_BUFFER_T SWUpdateBuffer[ NUM_OF_SW_UPDATE_MBOXES ]; ///< Software update buffer array. // ********** private function prototypes ******** /*********************************************************************//** * @brief * The initCommBuffers function initializes the CommBuffers unit. * @details Inputs: none * @details Outputs: CommBuffers unit initialized. * @return none *************************************************************************/ void initCommBuffers( void ) { SW_UPDATE_CAN_MAIL_BOX_T mailBox; for ( mailBox = SW_UPDATE_NOT_USED; mailBox < NUM_OF_SW_UPDATE_MBOXES; mailBox++ ) { clearCommBuffer( mailBox ); } } /*********************************************************************//** * @brief * The addToCommBuffer function adds data of specified length to a given * communication buffer. * @note This function will add to the active side of the double buffer. * @note This function is thread safe. IRQ interrupts are disabled during * buffer operations. * @details Inputs: SWUpdateBuffer[] * @details Outputs: SWUpdateBuffer[] * @param mailbox ID of buffer to add data to * @param data Pointer to byte array containing data to add to buffer * @param len Length of data (in bytes) * @return TRUE if data added to buffer successfully, FALSE if not *************************************************************************/ BOOL addToCommBuffer( SW_UPDATE_CAN_MAIL_BOX_T mailBox, U08* data, U32 len ) { BOOL status = FALSE; if ( mailBox < NUM_OF_SW_UPDATE_MBOXES ) { _disable_IRQ(); U32 currentFrameCount = SWUpdateBuffer[ mailBox ].SWUpdateFrameCount; // Check if the number of bytes is less than the allowed bytes in the mailbox buffer. if ( ( currentFrameCount * CAN_MESSAGE_PAYLOAD_SIZE ) <= MAX_NUM_OF_CAN_BYTES ) { U32 currentBufferIndex = currentFrameCount * len; // Copy the received can frame into the buffer memcpy( SWUpdateBuffer[ mailBox ].SWUpdateBuffer + currentBufferIndex, data, len ); // Increment the current frame count SWUpdateBuffer[ mailBox ].SWUpdateFrameCount += 1; status = TRUE; } _enable_IRQ(); } return status; } /*********************************************************************//** * @brief * The getFromCommBuffer function fills a given byte array with a specified * number of bytes from a given buffer and returns the number of bytes * retrieved from the buffer. * @note This function will draw from the inactive side of the double buffer * and, if needed, switch double buffers to draw the rest of the requested data. * @note This function is thread safe. IRQ interrupts are disabled during buffer * operations. * @details Inputs: SWUpdateBuffer[] * @details Outputs: none * @param mailbox ID of buffer to retrieve data from * @param data Pointer to byte array to populate with buffer data * @param len Number of bytes to retrieve from buffer into given byte array. * @return the number of bytes retrieved. *************************************************************************/ BOOL getCommBuffer( SW_UPDATE_CAN_MAIL_BOX_T mailBox, U08* data, U32 len ) { BOOL status = FALSE; if ( ( mailBox < NUM_OF_SW_UPDATE_MBOXES ) && ( len <= MAX_NUM_OF_CAN_BYTES ) ) { _disable_IRQ(); memcpy( data, SWUpdateBuffer[ mailBox ].SWUpdateBuffer, len ); status = TRUE; _enable_IRQ(); } return status; } /*********************************************************************//** * @brief * The getNumberOfBytesInBuffer function determines how many bytes * are currently contained in a given comm buffer. Both sides of the * double buffers are considered for this. * @details Inputs: SWUpdateBuffer[] * @details Outputs: none * @param mailbox ID of buffer to get byte count for * @return the number of bytes currently in the given comm buffer. *************************************************************************/ S32 getNumberOfBytesInBuffer( SW_UPDATE_CAN_MAIL_BOX_T mailBox ) { S32 bytes = -1; if ( mailBox < NUM_OF_SW_UPDATE_MBOXES ) { bytes = SWUpdateBuffer[ mailBox ].SWUpdateFrameCount * CAN_MESSAGE_PAYLOAD_SIZE; } return bytes; } /*********************************************************************//** * @brief * The clearBuffer function clears (empties) a given buffer. * @note This function is thread safe. IRQ interrupts are disabled while * buffers are being cleared. * @details Inputs: none * @details Outputs: given buffer is cleared. * @param buffer ID of the buffer to clear * @return none *************************************************************************/ void clearCommBuffer( SW_UPDATE_CAN_MAIL_BOX_T mailBox ) { _disable_IRQ(); if ( mailBox < NUM_OF_SW_UPDATE_MBOXES ) { memset( &SWUpdateBuffer[ mailBox ], 0x0, sizeof( SW_UPDATE_BUFFER_T ) ); } _enable_IRQ(); } // ********** private functions ********** /**@}*/