CAN Problems

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CAN Problems

2,029 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klaschudi on Wed Mar 06 01:15:06 MST 2013
Hello,
I'm trying to send something over the CAN1-Bus. With the following code:

void can_init(unsigned char bitrate)
{
LPC_SC->PCONP |= (1 << PCCAN1); // enable can1 clock
LPC_SC->PCLKSEL0 |= (0x10 << PCLK_CAN1);// canclk = 60MHz

LPC_PINCON->PINSEL0 &= ~(3 << 0)&(3 << 2); // select can pin function
LPC_PINCON->PINSEL0 |= (1 << 0)|(1 << 2);

LPC_CAN1->MOD = (1 << 0);    // enter reset mode
LPC_CAN1->IER = 0;  // disable receive interrupts
LPC_CAN1->GSR = 0;    // Reset error counter when CANxMOD is in reset

LPC_CAN1->BTR = bitrate;
LPC_CAN1->MOD = 0x0;  // leave reset mode, enter normal operation mode

LPC_CANAF->AFMR |= (1 << 1); // all rx messages are accepted  (acceptance filter)

NVIC_EnableIRQ(CAN_IRQn);

LPC_CAN1->IER = 0x01; // Enable receive interrupts
}


uint8_t CAN1_SendMessage( CAN_MSG *pTxBuf )
{
  uint32_t CANStatus;

  CANStatus = LPC_CAN1->SR;
  if ( CANStatus & (1 << 2) )
  {
LPC_CAN1->TFI1 = pTxBuf->Frame;
LPC_CAN1->TID1 = pTxBuf->MsgID;
LPC_CAN1->TDA1 = pTxBuf->DataA;
LPC_CAN1->TDB1 = pTxBuf->DataB;
LPC_CAN1->CMR = (1 << 0)|(1 << 5);
return ( TRUE );
  }

  else if ( CANStatus & (1 << 10) )
  {
LPC_CAN1->TFI2 = pTxBuf->Frame;
LPC_CAN1->TID2 = pTxBuf->MsgID;
LPC_CAN1->TDA2 = pTxBuf->DataA;
LPC_CAN1->TDB2 = pTxBuf->DataB;
LPC_CAN1->CMR = (1 << 0)|(1 << 6);
return ( TRUE );
  }
  else if ( CANStatus & (1 << 18) )
  {
LPC_CAN1->TFI3 = pTxBuf->Frame;
LPC_CAN1->TID3 = pTxBuf->MsgID;
LPC_CAN1->TDA3 = pTxBuf->DataA;
LPC_CAN1->TDB3 = pTxBuf->DataB;
LPC_CAN1->CMR = (1 << 0)|(1 << 7);
return ( TRUE );
  }

  return ( FALSE );
}


But after setting the CMR-Register for the first time the Controller starts to periodically transmit CAN-Messages with a weird ID (0C889249...). And after sendig once with each Transmit Buffer they are all marked as busy.
I already tried the Local Self test, which seemed to be OK. So I don't think that this is a Hardware Problem.

Did I forget anything in the Initialisation?

Thanks for your help!
0 Kudos
Reply
6 Replies

1,760 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klaschudi on Wed Mar 06 09:49:09 MST 2013
Now i solved the problem:
It didn't work because there wasn't anything to send ACK's when I started analysing it with CANalyzer the strange behaviour disappeard...
0 Kudos
Reply

1,760 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klaschudi on Wed Mar 06 07:04:09 MST 2013
I solved a part of the Problem now:
I didn't had the right bitrate because the defines in the example seem to be wrong.
But the controller still sends out the same frame (ID and Data are OK) periodically (with a break of 50ms) when I start the first transmission. The buffer isn't available from then on.
Do I have to take care when the controller transmitted the Message and stop it then. Or what could be a reason for that behaviour?
thanks...
0 Kudos
Reply

1,760 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klaschudi on Wed Mar 06 03:40:48 MST 2013
No, i don't.
I can only see a Overload-Message on the Bus.
But why do i get a positive result for the self test? Doesn't that mean that everything between controller and transiver is right?
0 Kudos
Reply

1,760 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Mar 06 02:27:20 MST 2013
That's the Rambo version

I prefer to check transmit buffers and use a timer (or loop) :eek:

//Check status of Transmit Buffer 1
    if ([COLOR=Red]CANx->SR & (1<<2)[/COLOR])
    {
        /* Transmit Channel 1 is available */
        /* Write frame informations and frame data into its CANxTFI1,
         * CANxTID1, CANxTDA1, CANxTDB1 register */
        CANx->TFI1 &= ~0x000F0000;
        CANx->TFI1 |= (CAN_Msg->len)<<16;
        if(CAN_Msg->type == REMOTE_FRAME)
        {
            CANx->TFI1 |= (1<<30); //set bit RTR
        }
        else
        {
            CANx->TFI1 &= ~(1<<30);
        }
        if(CAN_Msg->format == EXT_ID_FORMAT)
        {
            CANx->TFI1 |= (1<<31); //set bit FF
        }
        else
        {
            CANx->TFI1 &= ~(1<<31);
        }

        /* Write CAN ID*/
        CANx->TID1 = CAN_Msg->id;

        /*Write first 4 data bytes*/
        data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
        CANx->TDA1 = data;

        /*Write second 4 data bytes*/
        data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
        CANx->TDB1 = data;

         /*Write transmission request*/
        if(self_recep)
             CANx->CMR = 0x30;
        else
             CANx->CMR = 0x21;
         return SUCCESS;
    }
    //check status of Transmit Buffer 2
    else if([COLOR=Red]CANx->SR & (1<<10)[/COLOR])
    {
        /* Transmit Channel 2 is available */
        /* Write frame informations and frame data into its CANxTFI2,
         * CANxTID2, CANxTDA2, CANxTDB2 register */
        CANx->TFI2 &= ~0x000F0000;
        CANx->TFI2 |= (CAN_Msg->len)<<16;
        if(CAN_Msg->type == REMOTE_FRAME)
        {
            CANx->TFI2 |= (1<<30); //set bit RTR
        }
        else
        {
            CANx->TFI2 &= ~(1<<30);
        }
        if(CAN_Msg->format == EXT_ID_FORMAT)
        {
            CANx->TFI2 |= (1<<31); //set bit FF
        }
        else
        {
            CANx->TFI2 &= ~(1<<31);
        }

        /* Write CAN ID*/
        CANx->TID2 = CAN_Msg->id;

        /*Write first 4 data bytes*/
        data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
        CANx->TDA2 = data;

        /*Write second 4 data bytes*/
        data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
        CANx->TDB2 = data;

        /*Write transmission request*/
        if(self_recep)
            CANx->CMR = 0x50;
        else
            CANx->CMR = 0x41;
        return SUCCESS;
    }
    //check status of Transmit Buffer 3
    else if ([COLOR=Red]CANx->SR & (1<<18)[/COLOR])
    {
        /* Transmit Channel 3 is available */
        /* Write frame informations and frame data into its CANxTFI3,
         * CANxTID3, CANxTDA3, CANxTDB3 register */
        CANx->TFI3 &= ~0x000F0000;
        CANx->TFI3 |= (CAN_Msg->len)<<16;
        if(CAN_Msg->type == REMOTE_FRAME)
        {
            CANx->TFI3 |= (1<<30); //set bit RTR
        }
        else
        {
            CANx->TFI3 &= ~(1<<30);
        }
        if(CAN_Msg->format == EXT_ID_FORMAT)
        {
            CANx->TFI3 |= (1<<31); //set bit FF
        }
        else
        {
            CANx->TFI3 &= ~(1<<31);
        }

        /* Write CAN ID*/
        CANx->TID3 = CAN_Msg->id;

        /*Write first 4 data bytes*/
        data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
        CANx->TDA3 = data;

        /*Write second 4 data bytes*/
        data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
        CANx->TDB3 = data;

        /*Write transmission request*/
        if(self_recep)
            CANx->CMR = 0x90;
        else
            CANx->CMR = 0x81;
        return SUCCESS;
    }
    else
    {
        return ERROR;
    }
But the main question is if you scope / receive correct signals / messages on your CAN bus :confused:
0 Kudos
Reply

1,760 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by klaschudi on Wed Mar 06 02:07:40 MST 2013
this is what i did for the local self test:

LPC_SC->PCONP |= (1 << PCCAN1); // enable can1 clock
LPC_SC->PCLKSEL0 |= (0x10 << PCLK_CAN1);// canclk = 60MHz
LPC_PINCON->PINSEL0 &= ~(3 << 0)&(3 << 2); // select can pin function
LPC_PINCON->PINSEL0 |= (1 << 0)|(1 << 2);

LPC_CANAF->AFMR |= (1 << 1); // all rx messages are accepted  (acceptance filter)

LPC_CAN1->MOD = 1; // enter reset mode
LPC_CAN1->MOD = (1 << 2); // enable local self test

NVIC_EnableIRQ(CAN_IRQn);

while (1)
{
LPC_CAN1->CMR |= 0x30;
LPC_CAN1->CMR |= 0x50;
LPC_CAN1->CMR |= 0x90;
}


I paused the Debugger in the loop and the MOD register was still 4. Is this the right procedure for the self test?
0 Kudos
Reply

1,760 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Mar 06 02:03:18 MST 2013
This is a standard Init and Send function and not showing much :confused:

If your Local Self Test was really working and now stopped working, you have a hardware :confused: problem or no correct CAN bus :confused:
0 Kudos
Reply