Index: App/Common.h =================================================================== diff -u -r55b24bf84d96e9c3137cb1e60e5bcd334a7573f4 -rbbd766eed69a6ae143a42731965848da85fd4500 --- App/Common.h (.../Common.h) (revision 55b24bf84d96e9c3137cb1e60e5bcd334a7573f4) +++ App/Common.h (.../Common.h) (revision bbd766eed69a6ae143a42731965848da85fd4500) @@ -54,6 +54,7 @@ #define CAP(v,u) ((v) > (u) ? (u) : (v)) #define RANGE(v,l,u) ((v) > (u) ? (u) : ((v) < (l) ? (l) : (v))) +#define INC_WRAP(v,l,u) ((v) == (u) ? (l) : ((v)+1)) #define MAX(a,b) ((a) < (b) ? (b) : (a)) #define MIN(a,b) ((a) > (b) ? (b) : (a)) Index: App/Services/CommBuffers.c =================================================================== diff -u -ree310a2e5262c05bf0dc0eb0d84da0ee50bac7fe -rbbd766eed69a6ae143a42731965848da85fd4500 --- App/Services/CommBuffers.c (.../CommBuffers.c) (revision ee310a2e5262c05bf0dc0eb0d84da0ee50bac7fe) +++ App/Services/CommBuffers.c (.../CommBuffers.c) (revision bbd766eed69a6ae143a42731965848da85fd4500) @@ -28,12 +28,16 @@ // ********** private data ********** -static U32 commBufferStartPos[NUM_OF_COMM_BUFFERS][2]; // for each buffer, where is start? -static U32 commBufferEndPos[NUM_OF_COMM_BUFFERS][2]; // for each buffer, where is end? -static U32 commBufferByteCount[NUM_OF_COMM_BUFFERS][2]; // for each buffer, how many bytes? -static U32 activeDoubleBuffers[NUM_OF_COMM_BUFFERS][2]; // for each buffer, which double buffer is being fed? +static U32 commBufferByteCount[NUM_OF_COMM_BUFFERS][2]; // for each buffer, how many bytes does it contain? (also index to next available) +static U32 activeDoubleBuffers[NUM_OF_COMM_BUFFERS]; // for each buffer, which double buffer is being fed right now? static U08 commBuffers[NUM_OF_COMM_BUFFERS][2][COMM_BUFFER_LENGTH]; // each is double buffered to avoid thread contention +// ********** private function prototypes ********** + +static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); +static U32 getRemainingByteCapacity( COMM_BUFFER_T buffer ); +static BOOL isCommBufferEmpty( COMM_BUFFER_T buffer ); + /************************************************************************* * @brief initCommBuffers * The initCommBuffers function initializes the CommBuffers module. @@ -50,12 +54,10 @@ // reset and zero out all buffers for ( b = 0; b < NUM_OF_COMM_BUFFERS; b++ ) { + activeDoubleBuffers[b] = 0; for ( d = 0; d < 2; d++ ) { - commBufferStartPos[b][d] = 0; - commBufferEndPos[b][d] = 0; commBufferByteCount[b][d] = 0; - activeDoubleBuffers[b][d] = 0; for ( l = 0; l < COMM_BUFFER_LENGTH; l++ ) { commBuffers[b][d][l] = 0; @@ -67,10 +69,13 @@ /************************************************************************* * @brief addToCommBuffer * The addToCommBuffer function adds data of specified length to a specified \n - * communication buffer. S/W fault if buffer too full to add data. + * communication buffer. S/W fault if buffer too full to add data. \n + * Only one function in one thread should be calling this function. It is \n + * assumed that this thread will be higher priority than the thread calling \n + * the getFromCommBuffer() function so no thread protection is given. * @details - * Inputs : none - * Outputs : commBuffers[] + * Inputs : commBufferByteCount[], activeDoubleBuffers[] + * Outputs : commBuffers[], commBufferByteCount[] * @param buffer : which comm buffer to add data to * @param data : pointer to byte array containing data to add * @param len : length of data (in bytes) @@ -79,24 +84,174 @@ BOOL addToCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 len ) { BOOL result = FALSE; + U32 activeBuffer = activeDoubleBuffers[buffer]; + // verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + // check to make sure buffer is not too full to service this add + if ( len <= getRemainingByteCapacity( buffer ) ) + { + U08 *buffPtr; // buffer destination for added data + U08 *srcPtr; // data source + U32 dstIndex; // where to start adding bytes in destination buffer + U32 i; + + // get destination pointer to first available byte in buffer + dstIndex = commBufferByteCount[buffer][activeBuffer]; + buffPtr = &commBuffers[buffer][activeBuffer][dstIndex]; + // get source pointer to start of given data array + srcPtr = data; + // copy source data to destination buffer + for ( i = 0; i < len; i++ ) + { + *buffPtr++ = *srcPtr++; + } + // adjust buffer count per this data add + commBufferByteCount[buffer][activeBuffer] += len; + } + else // buffer too full to add this much data + { + // TODO - s/w fault? + } + } + else // invalid buffer given + { + // TODO - s/w fault + } + return result; } /************************************************************************* * @brief getFromCommBuffer * The getFromCommBuffer function fills a given byte array with data from \n - * a given buffer and returns the number of bytes retrieved from the buffer. + * a given buffer and returns the number of bytes retrieved from the buffer. \n + * Only one function in one thread should be calling this function. * @details - * Inputs : none - * Outputs : none - * @param none + * Inputs : commBuffers[], commBufferByteCount[] + * Outputs : commBufferByteCount[], activeDoubleBuffers[] + * @param buffer : which comm buffer to retrieve data from + * @param data : pointer to byte array to stuff data into + * @param maxLen : maximum # of bytes to retrieve into given data array. * @return the number of bytes retrieved. *************************************************************************/ U32 getFromCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 maxLen ) { U32 result = 0; + // verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + // check to see if anything in buffer + if ( FALSE == isCommBufferEmpty( buffer ) ) + { + // switch double buffer (now we'll read from what was active buffer and Rx interrupts will feed new active buffer) + U32 activeBuffer = switchDoubleBuffer( buffer ); + U32 inactiveBuffer = ( activeBuffer == 0 ? 1 : 0 ); + U32 bytesRetrieved = commBufferByteCount[buffer][inactiveBuffer]; + + // ensure caller's data buffer can hold the data we have to retrieve + if ( bytesRetrieved <= maxLen ) + { + U08 *buffPtr; // buffer source for retrieved data + U08 *dstPtr; // buffer destination for retrieved data + U32 i; + + // get source pointer to start of comm buffer + buffPtr = &commBuffers[buffer][inactiveBuffer][0]; + // get destination pointer to start of given data array + dstPtr = data; + // copy source data to destination buffer + for ( i = 0; i < bytesRetrieved; i++ ) + { + *dstPtr++ = *buffPtr++; + } + // reset inactive buffer after data retrieved from it + commBufferByteCount[buffer][inactiveBuffer] = 0; + } + else // not enough space in caller's buffer + { + // TODO - s/w fault? + } + } + else // buffer is empty + { + // result already set to zero + } + } + else // invalid buffer given + { + // TODO - s/w fault + } + return result; } +/************************************************************************* + * @brief switchDoubleBuffer + * The switchDoubleBuffer function switches the active and inactive buffers \n + * for the given buffer. + * @details + * Inputs : activeDoubleBuffers[] + * Outputs : activeDoubleBuffers[], commBufferByteCount[] + * @param buffer : which comm buffer to switch double buffers on + * @return the new active buffer for the given buffer. + *************************************************************************/ +static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ) +{ + U32 activeBuffer = activeDoubleBuffers[buffer]; + U32 inactiveBuffer = ( activeBuffer == 0 ? 1 : 0 ); + + // ensure inactive buffer is reset before making active + commBufferByteCount[buffer][inactiveBuffer] = 0; + // switch buffers + activeDoubleBuffers[buffer] = inactiveBuffer; + + // return the new active buffer (was just inactive) + return inactiveBuffer; +} + +/************************************************************************* + * @brief getRemainingByteCapacity + * The getRemainingByteCapacity function determines the remaining capacity \n + * of the given buffer. + * @details + * Inputs : commBufferByteCount[], activeDoubleBuffers[] + * Outputs : none + * @param buffer : which comm buffer to check the capacity of + * @return the number of bytes of capacity remaining in the buffer. + *************************************************************************/ +static U32 getRemainingByteCapacity( COMM_BUFFER_T buffer ) +{ + U32 result; + U32 activeBuffer = activeDoubleBuffers[buffer]; + + result = COMM_BUFFER_LENGTH - commBufferByteCount[buffer][activeBuffer]; + + return result; +} + +/************************************************************************* + * @brief isCommBufferEmpty + * The isCommBufferEmpty function determines whether a given comm buffer \n + * is empty. + * @details + * Inputs : commBufferByteCount[], activeDoubleBuffers[] + * Outputs : none + * @param buffer : which comm buffer to check for empty + * @return TRUE if the given comm buffer is empty, FALSE if not + *************************************************************************/ +static BOOL isCommBufferEmpty( COMM_BUFFER_T buffer ) +{ + BOOL result = FALSE; + U32 activeBuffer = activeDoubleBuffers[buffer]; + + if ( commBufferByteCount[buffer][activeBuffer] == 0 ) + { + result = TRUE; + } + + return result; +} + Index: HD.dil =================================================================== diff -u -ree310a2e5262c05bf0dc0eb0d84da0ee50bac7fe -rbbd766eed69a6ae143a42731965848da85fd4500 --- HD.dil (.../HD.dil) (revision ee310a2e5262c05bf0dc0eb0d84da0ee50bac7fe) +++ HD.dil (.../HD.dil) (revision bbd766eed69a6ae143a42731965848da85fd4500) @@ -1,4 +1,4 @@ -# RM46L852PGE 10/08/19 09:16:25 +# RM46L852PGE 10/08/19 14:27:47 # ARCH=RM46L852PGE # @@ -4268,7 +4268,7 @@ DRIVER.CAN.VAR.CAN_1_PORT_TX_DIR.VALUE=1 DRIVER.CAN.VAR.CAN_1_MESSAGE_5_EOB.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_1_MESSAGE_5_DIR.VALUE=0x20000000 -DRIVER.CAN.VAR.CAN_1_MESSAGE_2_INT_ENA_REF.VALUE=0x00000000 +DRIVER.CAN.VAR.CAN_1_MESSAGE_2_INT_ENA_REF.VALUE=0x00000001 DRIVER.CAN.VAR.CAN_3_MESSAGE_1_ENA.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_3_RAM_PARITY_ENA.VALUE=0x00000005 DRIVER.CAN.VAR.CAN_3_PHASE_SEG.VALUE=3 @@ -4609,7 +4609,7 @@ DRIVER.CAN.VAR.CAN_1_MESSAGE_35_BOOL_ENA.VALUE=0 DRIVER.CAN.VAR.CAN_1_MESSAGE_27_BOOL_ENA.VALUE=0 DRIVER.CAN.VAR.CAN_1_MESSAGE_19_BOOL_ENA.VALUE=0 -DRIVER.CAN.VAR.CAN_1_MESSAGE_2_INT_ENA.VALUE=0x00000000 +DRIVER.CAN.VAR.CAN_1_MESSAGE_2_INT_ENA.VALUE=0x00000400 DRIVER.CAN.VAR.CAN_2_PORT_TX_DOUT.VALUE=1 DRIVER.CAN.VAR.CAN_2_MESSAGE_31_RTR.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_2_MESSAGE_23_RTR.VALUE=0x00000000 @@ -4988,7 +4988,7 @@ DRIVER.CAN.VAR.CAN_2_MESSAGE_7_MASK.VALUE=0x000007FF DRIVER.CAN.VAR.CAN_1_MESSAGE_59_ENA.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_1_MESSAGE_2_BOOL_ENA.VALUE=1 -DRIVER.CAN.VAR.CAN_1_MESSAGE_1_INT_ENA.VALUE=0x00000000 +DRIVER.CAN.VAR.CAN_1_MESSAGE_1_INT_ENA.VALUE=0x00000800 DRIVER.CAN.VAR.CAN_3_MESSAGE_50_ID.VALUE=50 DRIVER.CAN.VAR.CAN_3_MESSAGE_42_ID.VALUE=42 DRIVER.CAN.VAR.CAN_3_MESSAGE_34_ID.VALUE=34 @@ -5119,7 +5119,7 @@ DRIVER.CAN.VAR.CAN_1_SYNC.VALUE=1 DRIVER.CAN.VAR.CAN_3_MESSAGE_11_INT_ENA_REF.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_3_SHIFT.VALUE=0 -DRIVER.CAN.VAR.CAN_1_MESSAGE_1_INT_ENA_REF.VALUE=0x00000000 +DRIVER.CAN.VAR.CAN_1_MESSAGE_1_INT_ENA_REF.VALUE=0x00000001 DRIVER.CAN.VAR.CAN_3_PORT_RX_PULDIS.VALUE=0 DRIVER.CAN.VAR.CAN_3_MESSAGE_60_BOOL_ENA.VALUE=0 DRIVER.CAN.VAR.CAN_3_MESSAGE_52_BOOL_ENA.VALUE=0 @@ -5275,7 +5275,7 @@ DRIVER.CAN.VAR.CAN_1_MESSAGE_44_INT_ENA.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_1_MESSAGE_36_INT_ENA.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_1_MESSAGE_28_INT_ENA.VALUE=0x00000000 -DRIVER.CAN.VAR.CAN_1_MESSAGE_1_MASK.VALUE=0x00000004 +DRIVER.CAN.VAR.CAN_1_MESSAGE_1_MASK.VALUE=0x000007FF DRIVER.CAN.VAR.CAN_3_MESSAGE_63_ID.VALUE=63 DRIVER.CAN.VAR.CAN_3_MESSAGE_55_ID.VALUE=55 DRIVER.CAN.VAR.CAN_3_MESSAGE_47_ID.VALUE=47 @@ -5499,7 +5499,7 @@ DRIVER.CAN.VAR.CAN_3_MESSAGE_16_BOOL_ENA.VALUE=0 DRIVER.CAN.VAR.CAN_3_MESSAGE_10_MASK.VALUE=0x000007FF DRIVER.CAN.VAR.CAN_1_MESSAGE_8_BOOL_ENA.VALUE=0 -DRIVER.CAN.VAR.CAN_1_MESSAGE_2_MASK.VALUE=0x00000005 +DRIVER.CAN.VAR.CAN_1_MESSAGE_2_MASK.VALUE=0x000007FF DRIVER.CAN.VAR.CAN_3_MESSAGE_59_ID.VALUE=59 DRIVER.CAN.VAR.CAN_3_MESSAGE_50_RTR.VALUE=0x00000000 DRIVER.CAN.VAR.CAN_3_MESSAGE_42_RTR.VALUE=0x00000000 Index: source/can.c =================================================================== diff -u -ree310a2e5262c05bf0dc0eb0d84da0ee50bac7fe -rbbd766eed69a6ae143a42731965848da85fd4500 --- source/can.c (.../can.c) (revision ee310a2e5262c05bf0dc0eb0d84da0ee50bac7fe) +++ source/can.c (.../can.c) (revision bbd766eed69a6ae143a42731965848da85fd4500) @@ -196,9 +196,9 @@ } /* Wait */ - canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000004U & (uint32)0x000007FFU) << (uint32)18U); + canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U); canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U); - canREG1->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000080U | (uint32)8U; + canREG1->IF1MCTL = 0x00001000U | (uint32)0x00000800U | (uint32)0x00000000U | (uint32)0x00000080U | (uint32)8U; canREG1->IF1CMD = (uint8) 0xF8U; canREG1->IF1NO = 1U; @@ -215,9 +215,9 @@ { } /* Wait */ - canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000005U & (uint32)0x000007FFU) << (uint32)18U); + canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U); canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x000007FFU) << (uint32)18U); - canREG1->IF2MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000080U | (uint32)8U; + canREG1->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000080U | (uint32)8U; canREG1->IF2CMD = (uint8) 0xF8U; canREG1->IF2NO = 2U;