MPC5775K FlexCAN CAN0

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

MPC5775K FlexCAN CAN0

3,865 Views
ronliu
Contributor IV

Dear All,

I'm using the MPC5775K now. But the CAN0 ( FlexCAN module) can not work well. And the program is always suspending in the below line.

 

while ( (CAN_0.IFLAG1.B.BUF31TO8I & 1) == 0) { } // wait until the tx is completed.

 

This problem bothers me all the day. Could someone give me advice about the CAN0, please? It would be better if you can share me the example code of  FlexCAN.

Thanks a lot.

 

Regards,

Ron

 

Martin Kovar

Labels (1)
Tags (2)
26 Replies

2,034 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

Look at this example. It shows, how to configure FlexCAN modules, and how to transmit and receive data. But be careful about FlexCAN modules connection. Correct connection is described in the example description.

Example MPC5775K FlexCAN_with_interrupts S32DS

If you have any other questions, please feel free to write me back.

Regards,

Martin

2,034 Views
ronliu
Contributor IV

Hi Martin,

I find that the sample can work correctly if I create the S32DS project in the single core mode. In single core mode, the below part doesn't processed. But if I create a new project in multi-core mode, the CAN module wouldn't work well. The hw_init() function is added by the S32 IDE. I don't know why this problem happens in mutli-core mode.  Thanks.

Regard,

Ron

sample code:

void hw_init(void)

{

#if defined(TURN_ON_CPU1) || defined(TURN_ON_CPU2)

uint32_t mctl = MC_ME.MCTL.R;

#endif

#if defined(TURN_ON_CPU1)

/* enable core 1 in all modes */

MC_ME.CCTL2.R = 0x00FE;

/* Set Start address for core 1: Will reset and start */

MC_ME.CADDR2.R = 0x1100000 | 0x1;

#endif

#if defined(TURN_ON_CPU2)

/* enable core 2 in all modes */

MC_ME.CCTL3.R = 0x00FE;

/* Set Start address for core 2: Will reset and start */

MC_ME.CADDR3.R = 0x1200000 | 0x1;

#endif

#if defined(TURN_ON_CPU1) || defined(TURN_ON_CPU2)

MC_ME.MCTL.R = (mctl & 0xffff0000ul) | KEY_VALUE1;

MC_ME.MCTL.R =  mctl; /* key value 2 always from MCTL */

#endif

}

0 Kudos

2,038 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

try this multicore. I tested it and it works correct. There is function hw_init, which boots cores Z7 (this function is created by S32). This function is called during startup. Function HW_Init initializes FMPLL, peripheral clocks and other hardware.

About EVB connection there is not necessary to use connection, which I write in my first project. You can use jumpers J32 and J35 fitted and jumpers J37 and J38 fitted in the position 2-3.

Regards,

Martin

2,038 Views
ronliu
Contributor IV

Thanks Martin,

fault.png

When I want to try the sample code, this problem occurs. Do I have to configure the IDE or the project ?

Regards,

Ron

0 Kudos

2,038 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

no, I use default project also IDE settings. But I have an idea. Exit S32DS, switch to the Windows task manager and kill processes s32de.exe and power-pc-eabivle-gdb.exe. Next step, right click on project and select Clean Project. Then build project again. Last step is to click on the arrow next to the bug and select MPC5775K-CAN_with_interrupts_Multicore-S32DS_LaunchGroup (look at the figure in the attachment). Now it should be OK.

Password for connection is DEAD_DEED_FADE_BADE

Regards,

Martin

2,038 Views
ronliu
Contributor IV

what do you mean about "Password for connection is DEAD_DEED_FADE_BADE"?

0 Kudos

2,038 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

if you want to debug the project using PEMicro USB multilink, you have to enter this password during the connecting to the device.

Regards,

Martin

2,038 Views
ronliu
Contributor IV

Hi, Martin

When I check your sample code, I couldn't find the function "void hw_init(void)".

I don't understand why the function is created in my new project by IDE default mode. But I couldn't find it in your project.

Thanks.

Regards,

Ron

0 Kudos

2,038 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

function hw_init is created automatically by IDE when you create multicore project. This function starts other Z7 core(s) and it is called during startup (Startup.s file). If you open startup file you will see the calling of the function before function main is called. Calling of the function hw_init is conditioned by HW_INIT symbol definition. But you can modify the startup file and start other cores wherever you want. You can look at this project:

Example MPC5775K PinToggleStationery S32DS

You can find defined symbols in project Properties/C/C++ build/Assembler Symbols

In single core projects IDE does not create hw_init function, because only Z4 core starts.

Regards,

Martin

2,038 Views
ronliu
Contributor IV

Martin,

Thanks for your help again !  :smileylaugh: With your direction, my project can work now.  But there is a strange issues always troubling me. I don't understand why the flexCAN module can work correctly only when I close HW_INIT symbol. In my opinion , there might be some conflict between multicore and CAN. :smileyshocked:

Regards,

Ron

0 Kudos

2,038 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

just a simple idea. Try to change the define in flashrchw.c file. There is #define MPC57xx_ID 0x005A0000 change the value to 0x005A0001. There is not any problem with CAN in multicore project. I had tried and it worked fine.

Regards,

Martin

2,038 Views
ronliu
Contributor IV

Martin,

Thanks. I changed the MPC57xx_ID value to 0x005A0001. But my project still cannot work when I call the function"void CORE_INIT(void)". Maybe there are something wrong with my project. However , I couldn't figure it out now.

Regards,

Ron

void CORE_INIT(void)
{
    /* Enable cores if running from RAM or not using the BAF to boot cores*/
    /* Enable Cores - Will start on next mode transistion */

    /* Enable or disable core 0 (Z4 - Lock Step Core) */
    MC_ME.CCTL1.R = 0x00FE;  /* enable core */
//      MC_ME.CCTL[1].R = 0x0000; /* disable core */

    /* Enable or disable core 1 (z7a) */
    MC_ME.CCTL2.R = 0x00FE;  /* enable core */
//      MC_ME.CCTL[2].R = 0x0000; /* disable core */


    /* Enable or disable core 2 (z7b)*/
    MC_ME.CCTL3.R = 0x00FE;  /* enable core */
//      MC_ME.CCTL[3].R = 0x0000; /* disable core */
}

0 Kudos

2,033 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

it seems that your function is not written correct. I do not see there mode transition. If you want to boot Z7 cores use this construction:

#define KEY_VALUE1 0x5AF0ul

#define KEY_VALUE2 0xA50Ful

void CORE_INIT(void)

{

    uint32_t mctl = MC_ME.MCTL.R;

  

   MC_ME.CCTL2.R = 0x00FE;

    /* Set Start address for core 1: Will reset and start */

    MC_ME.CADDR2.R = 0x1100000 | 0x1;

  

   MC_ME.CCTL3.R = 0x00FE;

    /* Set Start address for core 2: Will reset and start */

    MC_ME.CADDR3.R = 0x1200000 | 0x1;

   /*Mode transition*/

    MC_ME.MCTL.R = (mctl & 0xffff0000ul) | KEY_VALUE1;

    MC_ME.MCTL.R =  mctl; /* key value 2 always from MCTL */

}

Z4 core is the main core and this boot automatically. You cannot choose which core will be boot first. It is always Z4. From Z4 core you can boot other two cores.

Regards,

Martin

2,033 Views
ronliu
Contributor IV

Martin,

Thanks!

There are still something wrong with my multicore project . I have more urgent thing to do . I want to transfer a very large array by CAN bus now . So I create a new function to finish it. How do I check the CAN tx status? I have tried this code ,but some messages are lost.

Regards,

Ron

CAN.png

0 Kudos

2,033 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

you cannot check BUF31TO81 in the last while loop, because you use MB0. You have to check BUF0I bit. Once the message from MB0 is sent, BUF0I flag is set.

Regards,

Martin

2,035 Views
ronliu
Contributor IV

Martin,

Thanks, I correct this line . But the result is the same. When I want to send a large buffer , some messages are lost.  My real test shows that I only can get the first message and the last message , and other messages are lost.

while ((CAN_0.IFLAG1.B.BUF0I & 1) == 0) {}

Now I just want to send a large frame  per 8bytes every time. But I'm not sure the method to check TX module whether is idle or busy. So could you give some examples?

Regards ,

Ron

0 Kudos

2,035 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

I posted here two examples. First example was for single core and second for multi core. In both example ware used function, which sends 8 byte data frame.

So please clarify me these points:

1) Is BUF0I flag set after transmitting MB0?

2) What is the other side which receive data?

3) Are you able to receive some data on the other side?

4) Did you check signal on the oscilloscope?

5) What does it mean that you get only first and last message? Do you mean first and last byte from frame or first and last sent frame?

You do not have to check if TX module is idle or busy. After the BUF0I flag is set, data are successfully transmitted and you can use MB again.

Could you please also clarify me the main idea how does your program should work?

Regards,

Martin

2,035 Views
ronliu
Contributor IV

Martin,

Actually, my CAN can work and send data. But the frame is not complete.  For example,  I try to send a same frame of 16 bytes,  which is including 00 01 02 ...1F. You can see the log in the picture. On in the fourth time , the frame is right.  Other four times, the MCU could not send a complete frame.  But I send the same array indeed.  I check the signal in an oscilloscope too. It shows that some messages really lost.

Regards

Ron

scope.png

0 Kudos

2,035 Views
martin_kovar
NXP Employee
NXP Employee

Hi Ron,

I analyzed your code. The function could be written in a better way, but If you use while ((CAN_0.IFLAG1.B.BUF0I & 1) == 0) {} in for loop, it should works correct. But you do not set some important fields in MB such as length of the frame, used ID and other. And because the MBs are placed in RAM memory, there should be some random data, which can cause problems.

Look at the following source code and set it in the same way except of data bytes.

CAN_0.MB[0].CS.B.CODE = 0x8;          //MB TX inactive

CAN_0.MB[0].ID.B.ID_STD = 0; //set message STD ID

CAN_0.MB[0].DATA.W[1] = 0xAABBCCDD;             //data1 set

CAN_0.MB[0].DATA.W[0] = 0x12345678;                 //data0 set

CAN_0.MB[0].CS.B.DLC = 8;                                          //message length 8 bytes

CAN_0.MB[0].CS.B.RTR = 0;                                          //remote frame disable

CAN_0.MB[0].CS.B.IDE = 0;                                           //extended bit disable

CAN_0.MB[0].CS.B.SRR = 0;                                          //not used with STD_ID

CAN_0.MB[0].CS.B.CODE = 0xC;                                  //MB once transmit dat

From my point of view, it is better to use 4 MBs instead of one. Then you do not have to wait until data are sent.

Regards,

Martin

2,035 Views
ronliu
Contributor IV

Hi,

It used to work in the right way before. But there was a strange problem happened to my CAN module. I could see TX signal in a scope. But when I connected TX and RX to the CANPHY chip. The TX signal disappeared. I didn't change anywhere in the code project. But there was really something changed.

0 Kudos