We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Infineons Dave generates the following code for FIFO-Reception of CAN-Messages:
// @Controller Infineon XC167CI-16F40 // // @Compiler Keil // // @Codegenerator 2.4 ubyte CAN_ubReadFIFO(ubyte ubObjNr, TCAN_SWObj *pstObj) { ubyte i,j; ubyte ubReturn; ubReturn = 2; if((CAN_HWOBJ[ubObjNr].uwCANPTR & 0x0700) == 0x0200) // if FIFO base object { j = aubFIFOReadPtr[ubObjNr / 2]; ubReturn = 0; if((CAN_HWOBJ[j].uwMSGCTR & 0x0300) == 0x0200) // if NEWDAT { CAN_HWOBJ[j].uwMSGCTR = 0xfdff; // clear NEWDAT // CANPTRn(new) = CANPTR(old) & ~(uword)FSIZEn | (CANPTRn(old) + 1) & FZIZEn aubFIFOReadPtr[ubObjNr / 2] = ((aubFIFOReadPtr[ubObjNr / 2] & ~(uword)(CAN_HWOBJ[ubObjNr].uwCANFCR & 0x001f)) | ((aubFIFOReadPtr[ubObjNr / 2] + 1) & (CAN_HWOBJ[ubObjNr].uwCANFCR & 0x001f))); // check if the previous message was lost if((CAN_HWOBJ[j].uwMSGCTR & 0x0c00) == 0x0800) // if set MSGLST { CAN_HWOBJ[j].uwMSGCTR = 0xf7ff; // reset MSGLST return(3); } for(i = 0; i < (CAN_HWOBJ[j].uwMSGCFG & 0x00f0) >> 4; i++) { pstObj->ubData[i] = CAN_HWOBJ[j].ubData[i]; } if(CAN_HWOBJ[j].uwMSGCFG & 0x04) // if extended identifier { pstObj->ulID = CAN_HWOBJ[j].ulCANAR; } else // if standard identifier { pstObj->ulID = CAN_HWOBJ[j].ulCANAR >> 18; } pstObj->uwMsgCfg = CAN_HWOBJ[j].uwMSGCFG; // check if the message was corrupted if((CAN_HWOBJ[j].uwMSGCTR & 0x0300) == 0x0200) // if NEWDAT { CAN_HWOBJ[j].uwMSGCTR = 0xfdff; // clear NEWDAT return(4); } ubReturn = 1; } } return(ubReturn); } // End of function CAN_ubReadFIFO
It seems to me that there is at least one bug: In the Line
CAN_HWOBJ[j].uwMSGCTR = 0xfdff; // clear NEWDAT
the complete register is set with a constant instead of only resetting the newdat-bits. Two lines later this register is checked for the MSGLost-Bits, which will never be true:
if((CAN_HWOBJ[j].uwMSGCTR & 0x0c00) == 0x0800) // if set MSGLST
Does anybody have an idea, what happens here?
Hi Joachim,
Sorry, I don't fully understand your question. It very well may be that Dave has a bug and if you think you have found one then you can send an email to Infineon so they can investigate it.
So I would add a comment about changing the bits in the CAN control register (MSGCTRLn). This register is formed by bit pairs and you need a mechanism in which the hardware and software can interact without destroying each another. You will find a table Setting/Resetting the Control and Status Element of the Message Control Registers (Table 21-8 in the peripheral manual)
Value of the 2-bitfield Function 00B (write) reserved (read) reserved 01B (write) Reset element (read) Element is reset 10B (write) Set element (read) Element is set 11B (write) Leave element unchanged (read) reserved
So your comment is incorrect, writing a value of 0xFDFF to the control register will result in changing the bit pair NEWDAT (bits [9:8]). You are writing a 01b which will clear the bit. All other bit pairs are written with 11b which means leave the element unchanged. This means only the NEWDAT bit pair is changed.
CAN_HWOBJ[j].uwMSGCTR = 0xFDFF; // clear NEWDAT
Hope that helps.
Hi Chris, thanks for your reply, I didn't realize this special mechanism to access the bit-pairs in the MSGCTRL-registers. Guess I need to study the datasheet more carefully in order to understand what "Dave" does ;-)