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
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
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
}
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
Thanks Martin,
When I want to try the sample code, this problem occurs. Do I have to configure the IDE or the project ?
Regards,
Ron
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
what do you mean about "Password for connection is DEAD_DEED_FADE_BADE"?
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
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
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
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
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
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 */
}
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
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
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
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
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
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
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
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.