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?