This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

CAN-Routines generated by Dave

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 ;-)