Help with LPC11C24 C_CAN controller

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

Help with LPC11C24 C_CAN controller

1,263 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Mon Oct 03 01:14:45 MST 2011
Hello,

i am a newbie with the NXP Cortex Type processor and NXP LPCxpresso 11C24 board, but i am interesting in this LPCxpresso boards.
Now i am trying to run the CAN Bus on my LPCxpresso 11C24 board.
I would like to use the C_CAN controller (according chapter 13 from the manual) and not the C_CAN ON-chip driver.
I could realized that the LED turned on when ANY CAN message received on the CAN Bus.
When i received a CAN Message i read following:
LPC_CAN->STAT & (1<<4)
That is the RXOK Bit that turned to HIGH when i message received.
I see that also in the debug mode on the CAN Periphery.
But were are the message information (like ID, MSG, DLC etc)
[U][/U]
I think the "CAN Initialization procedure is OK, otherwise the RXOK bit would not work.

Have anybody a idea were the problem is?

Thanks and best regards,

Max
0 Kudos
22 Replies

943 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Sat Oct 08 05:42:09 MST 2011
Now i understand :)

Thanks again Zero for you useful help!!
0 Kudos

943 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Sat Oct 08 05:31:43 MST 2011

Quote: Zero
Yes :eek:




Can you give me a hint?
0 Kudos

943 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat Oct 08 05:23:49 MST 2011

Quote:

Is there a failure in my calculation?        

Yes :eek:

Obviously you don't understand clock generation with PLL (see: UM block diagram).


Quote:

FCLKOUT = M * FCLKIN = (FCCO)/(2*P)&#61481;

PSEL / P is not dividing your FCLKOUT, it is used to generate (internal) FCCO :)
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Sat Oct 08 05:14:13 MST 2011
Hello,

i't a little bit confused about the AHB clock in this
CAN sample.
In the CAN_Init() function in the CAN_C example a AHB clock source of
48Mhz is described.
I took a look in the SYSCTL and read out the values in debug mode:

System PLL clock source select Register:
SYSPLLCLKSEL = 0x01
System PLL clock source = System oscillator

System PLL control register
SYSPLLCTRL = 0x23
Feedback divider M = 4
Post divider P = 2

Main clock source select register
MAINCLKSEL = 0x03
Clock source for main clock = System PLL clock out

System AHB clock divider register
SYSAHBCLKDIV = 0x01
System AHB clock divider = 1

Clock on LPCxpresso board is a 12Mhz Crystal

With this parameters i have calculated the AHB clock frequency:
- Source of PLL is 12Mhz
- Multiplier of PLL is 4: 12Mhz * 4 = 48Mhz
- Divider of PLL is 2: 48Mhz / 2 = 24Mhz
- Source of AHB is PLL out
- Divider of AHB is 1

Therefore i have a AHB clock value of 24Mhz

But in the example a AHB clock of 48Mhz is defined.

Is there a failure in my calculation?
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Thu Oct 06 07:07:18 MST 2011
Hi Zero,

thank you very much for your post!

The Problem was the UMASK bit in the CANIFy_MCTRL Register.
LPC_CAN->CANIF2_MCTRL
I took this not from the example because the example use a ID mask on 0x100.
I want to receive ALL messages and not only one.
Thus i can't use this example 1:1 in my application.
The LPCxpresso example was running and working without any problem, but
with using the 0x100 ID mask.

And i thougt when i set UMASK bit to 0 the mask will be ignored (as described in the user manual) :confused:

But now it works
 LPC_CAN->IF2_MCTRL = UMSK|0x0000;
Thanks for your help!!!
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Oct 06 05:28:08 MST 2011
Still don't know why you aren't using the working sample :confused:

Don't know what you've changed and what you haven't changed, but #14 changes will receive every message, otherwise you didn't copy the right lines of original sample :eek:


uint32_t MsgID;

void My_MessageConfig(void)
{
 LPC_CAN->IF1_CMDMSK = WR|MASK|ARB|CTRL|DATAA|DATAB;
 LPC_CAN->IF1_MCTRL = 0x0000;
 LPC_CAN->IF1_MSK1 = 0x0000;
 LPC_CAN->IF1_MSK2 = 0 << 2 ; //no mask
 LPC_CAN->IF1_ARB1 = 0x0000;
 LPC_CAN->IF1_ARB2 = ID_MVAL | (0 <<2);//receive all
 LPC_CAN->IF1_DA1 = 0x0000;
 LPC_CAN->IF1_DA2 = 0x0000;
 LPC_CAN->IF1_DB1 = 0x0000;
 LPC_CAN->IF1_DB2 = 0x0000;
 LPC_CAN->IF1_MCTRL = UMSK|EOB|DLC_MAX; //|RXIE
//transfer data to message RAM
 LPC_CAN->IF1_CMDREQ = 1;
 while( LPC_CAN->IF1_CMDREQ & IFCREQ_BUSY );
}

int main(void)
{
 MyInit();
 My_MessageConfig();
 while(1)
 {
  //read status
  while (!(LPC_CAN->STAT & STAT_RXOK));
  LPC_CAN->STAT &= ~STAT_RXOK;
  while ( LPC_CAN->IF2_CMDREQ & IFCREQ_BUSY );
  LPC_CAN->IF2_CMDMSK = RD|MASK|ARB|CTRL|INTPND|TREQ|DATAA|DATAB;
  LPC_CAN->IF2_CMDREQ = 1;    //read message
  while ( LPC_CAN->IF2_CMDREQ & IFCREQ_BUSY );
  MsgID = (LPC_CAN->IF2_ARB2 &0x1FFF) >> 2;
  //read message data here!!!!
 }
 return 0 ;
}
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Wed Oct 05 15:11:05 MST 2011

Quote: Zero
#1 Why are you trying to set 10 identical message objects?

#2 Make uo your mind which register you want to use for defining a message, IF1 or IF2?

#3 Where's your LPC_CAN->IF1_MCTRL setting?



#1 Changed

#2 Changed

#3 Added

(see updated code in post below)

With this changes the behaviour is the same.
No message received
But when i change

LPC_CAN->IF2_ARB2 = ID_MVAL | 0;
to
LPC_CAN->IF2_ARB2 = ID_MVAL | ((0x100) << 2);
the message will be received and i have the data in the LPC_CAN->IF2_Dxy registers. With this change, only a message with the ID of 0x100 will be received.

BTW, i send a standard frame message from a CAN testtool
ID=0x100
MSG=0x1234567890ABCDEF
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Oct 05 14:35:20 MST 2011
#1 Why are you trying to set 10 identical message objects?

#2 Make uo your mind which register you want to use for defining a message, IF1 or IF2?

#3 Where's your LPC_CAN->IF1_MCTRL setting?
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Wed Oct 05 14:19:35 MST 2011
Thank you Zero for your message.
I tried this out but there are no changes.
I can't receive any message.

Here are my code:

Initialization code:

void MyInit(void)
{
    //Step 1
    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 17);
    //Step 2
    LPC_SYSCON->PRESETCTRL |= (1 << 3);
    //Initialization
      if ( !(LPC_CAN->CNTL & (1 << 0)) )
      {
        /* If it's in normal operation already, stop it, reconfigure
        everything first, then restart. */
        LPC_CAN->CNTL |= (1 << 0);        /* Default state */
      }

    //This register determines the CAN clock signal.
    //The CAN_CLK is derived from the peripheral clock PCLK divided by the values in this register.
    //48Mhz / x = 8Mhz -> x = 6 = Divider -> Clock Divider Value = 0x05
    LPC_CAN->CLKDIV = 0x05;
    //Start Configurastion Bit Timing:
        LPC_CAN->CNTL |= (1 << 6);
        //Set Baudrate to 500kBaud at 8Mhz
        LPC_CAN->BT = 0x2301;
        //Set Baudrate prescaler extension register to 0x0000 (default)
        LPC_CAN->BRPE = 0x0000;
        //Stopp Configuration Bit Timing
        LPC_CAN->CNTL &= ~(1 << 6);

    /* Initialization finishes, normal operation now. */
    LPC_CAN->CNTL &= ~(1 << 0);
    while ( LPC_CAN->CNTL & (1 << 0) );

}
Message Configuration:

void My_MessageConfig(void) {

      uint32_t i;

        LPC_CAN->IF2_CMDMSK = WR|MASK|ARB|CTRL|DATAA|DATAB;

        LPC_CAN->IF2_MCTRL = 0x0000;

        LPC_CAN->IF2_MSK1 = 0x0000;
        LPC_CAN->IF2_MSK2 = 0 << 2 ; //no mask

        LPC_CAN->IF2_ARB1 = 0x0000;
        LPC_CAN->IF2_ARB2 = ID_MVAL | 0;

        LPC_CAN->IF2_DA1 = 0x0000;
        LPC_CAN->IF2_DA2 = 0x0000;
        LPC_CAN->IF2_DB1 = 0x0000;
        LPC_CAN->IF2_DB2 = 0x0000;

        /* Transfer data to message RAM */
        LPC_CAN->IF2_CMDREQ = 1;
        while( LPC_CAN->IF2_CMDREQ & IFCREQ_BUSY );
      
      return;
}
Main Code:

int main(void) {

    MyInit();
    My_MessageConfig();

    while(1) {

        //Warte bis eine Nachricht empfangen
        while ( !(LPC_CAN->STAT & STAT_RXOK) );
        LPC_CAN->STAT &= ~STAT_RXOK;

        LPC_CAN->IF2_CMDMSK = 0x7F;
        /* Start message transfer to object with New data*/
        LPC_CAN->IF2_CMDREQ = 1;
        while (  (LPC_CAN->IF2_CMDREQ & (1<<15)) );

    }
    return 0 ;
}
I can't see any failure :confused:
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Oct 05 13:38:36 MST 2011
Just reset receive masking

LPC_CAN->IF1_MSK1 = 0x0000;
LPC_CAN->IF1_MSK2 = 0 << 2 ; //no mask

LPC_CAN->IF1_ARB1 = 0x0000;
LPC_CAN->IF1_ARB2 = ID_MVAL | 0; 
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Wed Oct 05 13:33:21 MST 2011
I am on a point where i have no solution for my problem.

With the MSK1 and MSK2 register i want to show that i disabled any filtering, so that any message would pass the filter.
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Oct 05 11:05:56 MST 2011
I this a question or are you just carried away by enthusiasm for masking bits with mask registers?
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Wed Oct 05 05:09:39 MST 2011
Thanks for the hint!
With transfering the defined message opject to the RAM i receive the correct data. To problem was the MSGVAL bit in the IFx_ARB2 register that should be tramfered to the RAM.
But in the ARB2 register the ID must be defined.
When i define the ID that i will send, i receive the message.
But when i send i message with an another ID, i receive nothing.

CANIFx_MSK1 and CANIFx_MSK2 register are 0x0000;
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Oct 04 12:48:15 MST 2011
If you are leaving Basic mode, you have to define message objects (see function: CAN_ConfigureMessages(void))
and IF registers are not used as simple receive / transmit registers anymore :eek:
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Tue Oct 04 12:39:45 MST 2011
This example is working in my environment, but this example shows the C_CAN in Test mode.
In testmode following modes are possible:
- Silent mode
- Loop-Back mode
- Basic Mode

For transfering data, the Basic Testmode is the mode the is want to use.

                                    
Quote:
The CAN Core can be set in Basic mode by programming the Test Register bit BASIC to one. In this mode the CAN controller runs without the Message RAM.


In this case i need no Message RAM.
And it will work. I receive the CAN Data that i sent.

For my applications i think i can work with the Testmode.


I tried the operation without test mode, the normal mode.
To read the message data from the RAM i use following:

[FONT=Courier New][SIZE=3]while ( !(LPC_CAN->STAT & STAT_RXOK) );
        LPC_CAN->STAT &= ~STAT_RXOK;[/SIZE][/FONT]

[FONT=Courier New][SIZE=3]//Load all datas[/SIZE][/FONT]
[FONT=Courier New][SIZE=3]LPC_CAN->IF2_CMDMSK = 0x7F;[/SIZE][/FONT]

[FONT=Courier New][SIZE=3]//Load to message number 1[/SIZE][/FONT]
[FONT=Courier New][SIZE=3]LPC_CAN->IF2_CMDREQ = 0x01;[/SIZE][/FONT]

[FONT=Courier New][SIZE=3]//Wait until done[/SIZE][/FONT]
[FONT=Courier New][SIZE=3]while (  (LPC_CAN->IF2_CMDREQ & (1<<15)) );[/SIZE][/FONT]

In LPCxpresso Debug mode i can see the data in in the IF2 Data registers,

but the data is not the same as the CAN Message that i sent.


I can see no failures :confused:
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Oct 04 07:59:22 MST 2011
Is this a question?

Yes, there is a sample and no, it's a full working sample as described in it's readme :eek:
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Tue Oct 04 05:12:24 MST 2011
In the LPC11C14 example library there is a example for the C_CAN Controller, but only in TEST MODE.
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Mon Oct 03 04:53:53 MST 2011

Quote:

For communication on a CAN network, individual Message Objects are configured. The
Message Objects and Identifier Masks for acceptance filtering of received messages are
stored in the Message RAM.
All functions concerning the handling of messages are implemented in the Message
Handler. Those functions are the acceptance filtering, the transfer of messages between
the CAN Core and the Message RAM, and the handling of transmission requests as well
as the generation of the module interrupt.



Don't know what you are trying to learn, but I would strongly suggest to use a sample to understand the basic mechanism of this controller :)
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maxheadroom on Mon Oct 03 04:39:48 MST 2011
Yes i know this sample, but i did try it from the scratch.
The INIT procedure is almost the same as in the sample.

I think something is missing to have access to the data.
The user manuel says that the data are stored in the RAM.

Could it be that i must copy the RAM values to the IFx message register?
0 Kudos

944 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Mon Oct 03 04:12:58 MST 2011
What's wrong with the sample you used to copy this part ?

Did you read the user manual ?

What do you think about Message interface registers ?
0 Kudos