Flexcan CAN0 Tx Fails - SDK v2.2, MK20DX256VLL10

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

Flexcan CAN0 Tx Fails - SDK v2.2, MK20DX256VLL10

1,626 Views
Cdn_aye
Senior Contributor I

I have a working MQX 4.0.1 system for Tx of CAN0 messages on an in-house board using the MK20DX256VLL10.

I cannot get the correct timing for the messages using code from the example for flexcan on the same board, SDK v2.2. We are using the MCG in PEE mode. A 16Mhz xtal, clocked up to 96Mhz. This is working correctly I believe as it passes all the wait on LOCK tests.

We need to Tx on CAN0 at 500,000. When I look at the mcg registers between the mqx setup and sdk setup, they are identical for the key bits. There are some alerts and trim values that are different but the timing portions for dividers and clock selects are identical.

However the data viewed on the logic analyzer is completely wrong for the FreeRTOS & SDK v2.2 code. The values are wrong I believe because the baud rate is not right.

If I use kFLEXCAN_ClkSrcPeri as the clock, the code hangs waiting for exit from low power tests in fsl_clock.c. I have to use  kFLEXCAN_ClkSrcOsc

We are unable to set the clksrc as per the example, flexcanConfig.clkSrc            = kFLEXCAN_ClkSrcOsc; This gives a bit time on the first dominant bit of .75usec, in the working code the first bit is 2 usec and the data is totally wrong. Here is the working capture.

pastedImage_2.png

Here is the Flexcan from my SDK v2.2 code, with the same values for data. 

pastedImage_3.png

Sorry about the size; I can't get this web page to display it larger. As can be seen the data is not even close. I don't understand why I am even getting any response given the data is wrong?

If anyone can tell me what is wrong it would be very appreciated. I am assuming that flexcanConfig.length = 1, is an 8 byte frame. I can't find any documentation on this field other than the type. Is this correct?

I have no clue how to set these clocks based on the documentation. The doc set tells nothing I can find for the definitions for meaning and why a particular field should be one value or another, only programming data types. Can you tell me which clock output the CAN system should use if we are using the PLL in PEE mode, with an external xtal of 16Mhz, clocked to 96Mhz for the core? In MQX we just picked the baudrate and the RTOS driver set the correct dividers. Why do we have to set a baudrate and also a clock source, this seems counter intuitive since not all clock sources will work apparently. Which clock source should I use and how do I select it?

We generated the clock code using the Configuration Tool as well as the mux pin assignments. Thank you.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

char c_tx_buff[] = {0x02, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00};
char static c_rx_buff[8], c_test[8];

flexcan_handle_t flexcanHandle;
flexcan_mb_transfer_t txXfer;
flexcan_mb_transfer_t rxXfer;


flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;

flexcan_frame_t rxFrame;
flexcan_frame_t txFrame;

uint32_t u32_freq_bus, u32_freq_periph, u32_freq_osc_clk; // just for debug validation

FLEXCAN_GetDefaultConfig(&flexcanConfig);

flexcanConfig.baudRate = 500000U;
flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri; // default was kFLEXCAN_ClkOscOsc;

// u32_freq_osc_clk = flexcanConfig.clkSrc;
// u32_freq_periph = kFLEXCAN_ClkSrcPeri;
// u32_freq_bus = CLOCK_GetFreq(kCLOCK_BusClk);

FLEXCAN_Init(CAN0,
&flexcanConfig,
CLOCK_GetFreq(kCLOCK_BusClk));

FLEXCAN_TransferCreateHandle(CAN0, // Create FlexCAN handle structure and set call back function
&flexcanHandle,
flexcan_callback,
NULL);

FLEXCAN_SetRxMbGlobalMask(CAN0, // Set Rx Masking mechanism
FLEXCAN_RX_MB_STD_MASK(CAN0_RX_IDENTIFIER, 0, 0));

mbConfig.format = kFLEXCAN_FrameFormatStandard; // Setup Rx Message Buffer
mbConfig.type = kFLEXCAN_FrameTypeData; // remote frame data type
mbConfig.id = FLEXCAN_ID_STD(CAN0_RX_IDENTIFIER);

FLEXCAN_SetRxMbConfig(CAN0,
RX_MESSAGE_BUFFER_NUM,
&mbConfig,
true);

FLEXCAN_SetTxMbConfig(CAN0, // Setup Tx Message Buffer
CAN0_TX_MAILBOX_NUM,
true);

txFrame.id = FLEXCAN_ID_STD(CAN0_TX_IDENTIFIER);
txFrame.format = kFLEXCAN_FrameFormatStandard;
txFrame.type = kFLEXCAN_FrameTypeData;
txFrame.length = 1;

memcpy(&txFrame.dataWord0, &c_tx_buff[0], 4);
memcpy(&txFrame.dataWord1, &c_tx_buff[4], 4);

txXfer.frame = &txFrame;
txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM; // might be 1 of 16 buffers on CAN device, no doc on this

while(1){
FLEXCAN_TransferSendNonBlocking(CAN0,
&flexcanHandle,
&txXfer);

{
uint32_t u32_i = 0, u32_j = 0;
for(u32_i = 0; u32_i < 0xFFFFFF; u32_i++){
u32_j++;
}
}
}

9 Replies

915 Views
Cdn_aye
Senior Contributor I

Hi Xiangjun

I corrected the trap; I had a sequence of calls wrong.

But I still cannot Tx the data correctly. All the above was to verify the clock was correct. I am getting a lock on the mcg_s, and the CLKOUT is 48mhz, but the CAN0 timing is still wrong. I will contrast the CAN registers from the older MQX and new SDK and post if I can find out the problem,

Thanks

Robert

0 Kudos

915 Views
Cdn_aye
Senior Contributor I

Hi Xiangjun

I set the breakpoint before the FLEXCAN_Init executed. I stepped over and the SIM_SCGC  CAN0 clock is enabled as below. The problem is OSCERCLK is not enabled, and when I test the

FLEXCAN_TransferSendNonBlocking(CAN0,
&flexcanHandle,
&txXfer);
The data rate is wrong as per the previous screen capture. When I enable OSCERCLK I get the trap to the default unhandled interrupt exception. I need to know how to set up the mcg so I don't get the trap. If I can get the OSCERCLK working maybe the CAN0 transfer will work. Is it because OSCERCLK is enabled at the start of the setup, in clock_config.c? This setup calls code from fsl_clock, not my code. It was auto generated by the config tool

pastedImage_2.png

pastedImage_1.png

Regards

Robert

0 Kudos

915 Views
Cdn_aye
Senior Contributor I

Hi

I went through this example many times, changed the code to align and I still get the trap. I can see 48Mhz on the CLKOUT pin and when I read     u32_freq_bus = CLOCK_GetFreq(kCLOCK_BusClk); I get 48Mhz. If I enable the OSCERCLK the device traps.

This is a MK20DX256ZVLL10, however I have accounted for MCG_C7 and it is selected to the External Oscillator, and as I said this part works on the MQX system perfectly.

Here are the registers when it hits the FLEXCAN_Init, I have disabled the OSCERCLK or the system will not lock. As can be seen I have a lock on the PLL. Can you see anything in error? Someone suggested to use the low power mode for the MCG_C1  HGO0 fields, High Gain, Low Power... is that a reason? What I don't understand is why the system will trap, if it has a valid status lock on the PLL?

Do you have any suggestions?

Thanks

pastedImage_1.png

0 Kudos

915 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

It seems that you do not enable the flexcan gated clock, pls check it.

SIM_SCGC3|=0x10;

BR

Xiangjun Rong

0 Kudos

915 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

sorry, for flexcan0, you should set bit4 of  SIM_SCGC6. For flexcan1, you should set bit4 of SIM_SCGC3.

SIM_SCGC6|=0x10;

BR

Xiangjun Rong

0 Kudos

915 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Robert,

As you know that Can module can transfer data based on handshaking signal(ACK), so the two Can node should have the same baudrate.

Regarding the can module clock, pls refer to the following figure:

The OSCERCLK is the external clock from Extal0/Xtal0 pins, for you case, it is 16MHz because you connect clock source or crystal with 16MHz to the pins. The Bus clock is the bus clock, for your case, it is 48MHz if you run core/system clock in 96MHz. The CLKSRC bit in CANx_CTRL1 register determines which clock source is selected. From software perspective:

typedef enum _flexcan_clock_source
{
    kFLEXCAN_ClkSrcOsc = 0x0U,  /*!< FlexCAN Protocol Engine clock from Oscillator. */  16MHz external clock
    kFLEXCAN_ClkSrcPeri = 0x1U, /*!< FlexCAN Protocol Engine clock from Peripheral Clock. */ 48MHz bus clock
} flexcan_clock_source_t;

Regarding the baudrate of Can module, as you know that one CAN bit consists of multiple Can Serial Clock, the Can Serial Clock is  a divider of the FlexCAN clock.

1)Can Serial Clock frequency=(FlexCAN clock frequency)/Prescaler;

The Prescaler is defined PRESDIV bits in CANx_CTRL1 register, Prescaler=PRESDIV+1;

2)CAN bit rate is Can Serial Clock frequency/(1 + (PSEG1 + 1) + (PSEG2 + 1) + (PROPSEG + 1)])

The PSEG1,PSEG2 and PROPSEG bits are defined in CANx_CTRL1.

For the code, FLEXCAN_Init(CAN0,&flexcanConfig,CLOCK_GetFreq(kCLOCK_BusClk));

FLEXCAN_Init() function will figure out the PRESDIV, PSEG1,PSEG2 and PROPSEG bits based on your required baudrate(flexcanConfig.baudRate = 125000U;) and the FlexCAN clock.

In other words, if you use 16MHz external clock, you can call the functioin as :

FLEXCAN_Init(CAN0,&flexcanConfig,CLOCK_GetFreq(kCLOCK_Osc0ErClk));

or

FLEXCAN_Init(CAN0,&flexcanConfig,16000000); //CLOCK_GetFreq(kCLOCK_Osc0ErClk));

If you use bus clock as FlexCAN clock, pls call

FLEXCAN_Init(CAN0,&flexcanConfig,CLOCK_GetFreq(kCLOCK_BusClk));

It is important that the bardrate must match between two CAN node, for example all the can node should work in 500KHz, BTW, the internal IRC clock is not accurate, that is why we suggest you use external clock or PEE mode which also use external clock source as FlexCAN clock.

pls refer to section 46.4.8.4 Protocol timing in UM of K20.

Hope it can help you

BR

Xiangjun Rong

pastedImage_1.png

915 Views
Cdn_aye
Senior Contributor I

Hi Xiangjun

I enabled the Flexbus clock to the CKLOUT pin and can measured 48Mhz on the pin (it is now set to the flash clock at 24Mhz, but I checked it when it was the Flexbus clock). I made a mistake in writing above, the XTAL is 8Mhz. So I changed that through the Config tool and it is correct. The OSCERCLK output was not turned on, so I turned that on. However I now get traps to the default handler and cannot find out why. With the OSCERCLK not enabled, I still get the capture I showed above but no traps. I understand from your description and the reference manual that we have to have the OSCERCLK enabled, but as I said we get traps to the default handler and I don't know a way to determine what caused the trap. Do you have a suggestion?

I also found that in on the board, the capacitor across the XTAL was 18pf. I changed the configuration from 12pf to 18pf to reflect this value. However it makes no difference we still trap in the following code as soon as the PLL is enabled.

status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config)

{

...

CLOCK_EnablePll0(config);
}

/* Change to PLL mode. */
MCG->C6 |= MCG_C6_PLLS_MASK;

/* Wait for PLL mode changed. */
while (!(MCG->S & MCG_S_PLLST_MASK))
{
}

/////// trap occurs here /////////

return kStatus_Success;
}

If I load the working MQX code with the functional CAN0 Tx, everything works correctly. So the problem is not the hardware. I have uploaded the MEX file in case you can see anything there.

Thank you for the help

Robert

pastedImage_1.png

0 Kudos

914 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Robert,

It seems that you configure the OSCERCLK incorrectly, which leads to the chip trap.

we have an example from FEI to PEE mode, pls refer to the section:

25.5.3.1 Example 1: Moving from FEI to PEE mode: External Crystal =
4 MHz, MCGOUTCLK frequency = 48 MHz

Hope it can help you

BR

XiangJun Rong

0 Kudos

914 Views
Cdn_aye
Senior Contributor I

Hi Xiangjun

That is a great deal of help; a very good explanation. Thank you.

I will go through and recheck the clocks as you have described and let you know the results.

Robert

0 Kudos