K60 CAN Clocked with FLL driven by RTC Crystal

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

K60 CAN Clocked with FLL driven by RTC Crystal

2,959 次查看
norton256
Contributor III

Hello,

First the back story:

I have a system of four K60 devices which are communicating over the CAN Bus. When the communication is occurring, the device and peripheral is clocked from the FLL driven by the RTC crystal.

From a fresh power up the system has no problems communicating. Every time the system comes up establishes CAN communications and then proceeds to do what it does. Once it starts doing what it does, it no longer talks over CAN for a while and switches it's clock to the PLL Driven by OSC0.

On a command it switches it's clock mode back to RTC driven FLL, and then resumes CAN communications.

The problem:

After a variable number of clock source switches, CAN communications breaks down. There are many form and stuffing errors, as well as BIT1 errors.

I have been having great difficulty in tracking down the source of this issue. I've read vague rumblings about the FLL is not a good source for the CAN bus, but no firm documentation as to why.

Based on AN1798, the system should be able to tolerate at least a 1.4% to 1.5% clock error.

Any advice would be greatly appreciated.

标签 (1)
标记 (4)
0 项奖励
回复
20 回复数

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

First of all, sorry for the later reply.

Have you tried to initialize FlexCAN module after each clock source switching? If there still with the stuffing error or Bit1 error?


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

Below is the initialization I use:

      // start the initialization
      Hwi_clearInterrupt(K60CAN_MessageInterruptVectorNumber[obj->DeviceId]);
      Hwi_clearInterrupt(K60CAN_BusOffInterruptVectorNumber [obj->DeviceId]);
      Hwi_clearInterrupt(K60CAN_ErrorInterruptVectorNumber  [obj->DeviceId]);
      Hwi_clearInterrupt(K60CAN_TxWarnInterruptVectorNumber [obj->DeviceId]);
      Hwi_clearInterrupt(K60CAN_RxWarnInterruptVectorNumber [obj->DeviceId]);
      Hwi_clearInterrupt(K60CAN_WakeInterruptVectorNumber   [obj->DeviceId]);

      // enable the peripheral clock through the system integration module
      if (obj->DeviceId == 0)
      {
         SIM_SCGC6 |= SIM_SCGC6_FLEXCAN0_MASK;
      }
      else
      {
         SIM_SCGC3 |= SIM_SCGC3_FLEXCAN1_MASK;
      }

      // disable the CAN module
      //obj->RegPtr->MCR |= CAN_MCR_MDIS_MASK;

      // set CAN to use the bus clock
      obj->RegPtr->CTRL1 |= CAN_CTRL1_CLKSRC_MASK;

      // enable the CAN module
      obj->RegPtr->MCR &= ~CAN_MCR_MDIS_MASK;

      // wait until out of power power mode
      while((obj->RegPtr->MCR & CAN_MCR_LPMACK_MASK) != 0);

      // wait until into freeze mode
      while((obj->RegPtr->MCR & CAN_MCR_FRZACK_MASK) == 0);

      // enable individual Mailbox masks
      obj->RegPtr->MCR |= CAN_MCR_IRMQ_MASK;

      // disable self reception
      obj->RegPtr->MCR |= CAN_MCR_SRXDIS_MASK;

      // enable abort
      obj->RegPtr->MCR |= CAN_MCR_AEN_MASK;

      // enable local priority
      obj->RegPtr->MCR |= CAN_MCR_LPRIOEN_MASK;

      // get the current clock rate
      peripheralClockKHz = Clocking_GetClockkHz(Clocking_BUS_CLK);

      // configure the baud rate for the bus
      status = K60CAN_SetBaud(obj, peripheralClockKHz * 1000);

      // BUS OFF auto recovery ON
      obj->RegPtr->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK;

      // Bus Off Interrupt OFF
      //obj->RegPtr->CTRL1 &= ~CAN_CTRL1_BOFFMSK_MASK;
      // Bus Off Interrupt ON
      obj->RegPtr->CTRL1 |= CAN_CTRL1_BOFFMSK_MASK;

      // Error Interrupt OFF
      //obj->RegPtr->CTRL1 &= ~CAN_CTRL1_ERRMSK_MASK;
      // Error Interrupt ON
      obj->RegPtr->CTRL1 |= CAN_CTRL1_ERRMSK_MASK;

      // TX Warning Interrupt OFF
      //obj->RegPtr->CTRL1 &= ~CAN_CTRL1_TWRNMSK_MASK;
      // TX Warning Interrupt ON
      obj->RegPtr->CTRL1 |= CAN_CTRL1_TWRNMSK_MASK;

      // RX Warning Interrupt OFF
      //obj->RegPtr->CTRL1 &= ~CAN_CTRL1_RWRNMSK_MASK;
      // RX Warning Interrupt ON
      obj->RegPtr->CTRL1 |= CAN_CTRL1_RWRNMSK_MASK;

      // Wake Interupt OFF
      obj->RegPtr->MCR &= ~CAN_MCR_WAKMSK_MASK;
      // Wake Interupt ON
      //obj->RegPtr->MCR |= CAN_MCR_WAKMSK_MASK;

      // take the device out of halt mode
      obj->RegPtr->MCR &= ~CAN_MCR_HALT_MASK;

      // wait until out of freeze mode
      while((obj->RegPtr->MCR & CAN_MCR_FRZACK_MASK) != 0);

      // Turn off all interrupts
///   obj->RegPtr->IMASK1 = 0x00000000;
///   obj->RegPtr->IMASK2 = 0x00000000;

      // Clear all pending interrupts
///   obj->RegPtr->IFLAG1 = 0x0000FFFF;
///   obj->RegPtr->IFLAG2 = 0x0000FFFF;

      Hwi_enableInterrupt(K60CAN_MessageInterruptVectorNumber[obj->DeviceId]);
      Hwi_enableInterrupt(K60CAN_BusOffInterruptVectorNumber [obj->DeviceId]);
      Hwi_enableInterrupt(K60CAN_ErrorInterruptVectorNumber  [obj->DeviceId]);
      Hwi_enableInterrupt(K60CAN_TxWarnInterruptVectorNumber [obj->DeviceId]);
      Hwi_enableInterrupt(K60CAN_RxWarnInterruptVectorNumber [obj->DeviceId]);

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

I got the feedback from Kinetis product team with below comments:

If bus clock is from FLL, the high bit rate may not be achieved due to CAN clock tolerance requirement 1.58%

So, we recommend customer to use the PLL clock as FlexCAN module clock source.

If customer still want to use FLL clock as FlexCAN module clock source, customer need to slow down the CAN bus baud rate.

Before the FlexCAN module software reset, customer can disable the FlexCAN module.

Then, after FlexCAN module software reset, do the full initialization.


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

After looking a bit more, I believe I have arrived at a new theory on what is happening:

Errata: e7993 on the 120MHz K60 device.

Basically, the clock the device is running at is not the correct value.

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

Have you tried the e7993 provided workaround way? If that fix the issue?


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

I have implemented the errata workaround, but it ultimately did not help. Eventually after switching enough times the errors crop up again. I even have in my Error ISR to perform a software reset and re-init, but that still won't help it recover.

Except for the initial switch from FEI to FEE, I am switching clock modes between PEE and FEE. So I believe the errata only holds true for the first switch, not all of the subsequent ones where I am always in external clock mode.

Any additional info on the FLL accuracy?

Also any ideas on when I place the CAN peripheral in disable mode and perform a SW reset why it never comes out of SW reset?

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

FlexCAN module software reset doesn't work with FlexCAN module disable mode.

So, customer need to enable the FlexCAN module with below code and let module in Freeze mode.

Please refer below code for the detailed info:

   SIM_SCGC6 |= SIM_SCGC6_FLEXCAN0_MASK;
    CAN0_CTRL1 |= CAN_CTRL1_CLKSRC_MASK;
    CAN0_MCR |= CAN_MCR_FRZ_MASK;          // enable HALT feature
    CAN0_MCR &= ~CAN_MCR_MDIS_MASK;   //enable FlexCAN module
    while((CAN_MCR_LPMACK_MASK & CAN0_MCR));    

      // Now can apply Soft Reset
      CAN0_MCR |= CAN_MCR_SOFTRST_MASK;
      while(CAN_MCR_SOFTRST_MASK & CAN0_MCR);
         
       // Now it should be in Freeze mode  
       while(!(CAN_MCR_FRZACK_MASK & CAN0_MCR));

About more info of FLL accuracy, I need double check with Kinetis product team.

I will let you know when  there with any updated info. Thank you for the patience.


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

Any updates on the FLL accuracy?

After fixing the errata the reliability has increased, but is still only 50% to 80%

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

For the K60 datasheet doesn't provide the FLL Max. period jitter data, the Kinetis MCG module is using modified module from MCF51xx MCG module, and I check MCF51CN MCG module FLL Max. Long term Jitter of DCO output clock (averaged over 2ms interval) is 0.2%. I identify Kinetis MCG module with same performance as MCF51XX MCG module.

As the FlexCAN module also mentioned below info:

The oscillator clock should be selected whenever a tight tolerance (up to 0.1%) is required in the CAN bus timing. The oscillator clock has better jitter performance.

I would recommend customer to use PLL generated clock for FlexCAN module instead of using FLL generated clock.


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

Given that information I have been attempting to run the device in FBE mode with the external RTC as the input. In this mode the FLEXCAN module appears to get "stuck" in Freeze mode sometimes? It will not transmit or receive.

When I attempt to debug, it functions properly. But if I attach after the target has been running and not acting as it should, I notice that the MCR register has the freeze ack bit set, even though the halt bit is not set.

Any idea how this could happen?

Again, I do not have access to an external clock which can drive the PLL in this hardware.

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

The FlexCAN module clock source could from Bus clock or from OSCERCLK.

From your description, the MCG works in FBE mode with external 32KHz crystal clock.

So, I think the FlexCAN module clock is 32KHz clock, right?

pastedImage_1.png

And the core and bus clock is also 32KHz, right?

The CANx_MCR[FRZACK] bit will be set with the CANx_MCR[HALT] bit is set.

If it possible, could you attach your tested code here? Thanks.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

That is correct that the whole system is running off of the 32KHz clock, with the CAN module set to use the bus clock.

0 项奖励
回复

2,664 次查看
norton256
Contributor III

When a K60 is halted from the debugger, does the CAN peripheral essentially go into freeze mode? Other peripherals explain how they react when the debugger takes control, but the CAN module does not.

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

The FlexCAN module has below description about MCR[FRZ_ACK] bit. When debugger halt the MCU, this bit will be set. So, your previous observed this bit is set during debug is normal.

pastedImage_1.png


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

I have tried baud rates from 1k to 100k. All with the same results.

In my hardware, when I require the CAN bus to be functional, I only have the internal oscillators (which have a horrible tolerance), and the RTC crystal. I do not have an oscillator available to drive the PLL.

What about the FLL generates such a bad clock tolerance? Given a particular input clock tolerance rating, what is the tolerance output of the FLL?

The FLL period jitter spec is 180ps. In comparison to 24MHz, that is a pretty small fraction.

I will attempt disable, followed by SW reset, then full init.

0 项奖励
回复

2,664 次查看
norton256
Contributor III

When I disable the peripheral and then run a SW reset, the code hangs waiting for the reset to complete.

Here is the code snippet:

// command the reset
obj->RegPtr->MCR |= CAN_MCR_SOFTRST_MASK;

// while the reset bit is still high, reset has not yet completed
while((obj->RegPtr->MCR & CAN_MCR_SOFTRST_MASK) != 0); <--- stuck here

0 项奖励
回复

2,664 次查看
norton256
Contributor III

After each clock switch I reprogram the required baud and timing registers only. But I do not halt (enter freeze) the peripheral before I switch the clocks.

Are you suggesting that I perform a soft reset on the CAN peripheral and then perform a full re-initialization?

0 项奖励
回复

2,664 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

After the clock switch, I recommend do a FlexCAN module software reset and then with a full re-initialization.

For the FlexCAN software reset doesn't affect CTRL1, CTRL2, RXIMR0–RXIMR63, RXMGMASK, RX14MASK, RX15MASK, RXFGMASK, RXFIR, all Message Buffers. Customer need to make sure previous setting value in those registers be cleared before set a new value.

pastedImage_1.png


Wish it helps.

Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复

2,664 次查看
norton256
Contributor III

I have tried the following and none of them have removed the problem:

Disable CAN controller before clock switch then Software Reset and Re-Init as if from scratch after clock switch

If an error interrupt occurs, Software Reset and Re-Init as if from scratch

Frame the clock switch with entering freeze mode

Frame the clock switch with disabling the module

I'm running out of ideas.

Again, I also posted my init code, so if there is something wrong there I would appreciate feedback.

Thanks

0 项奖励
回复

2,664 次查看
norton256
Contributor III

I have some order of operations questions:

Can I just request a soft reset at any time?

Should I issue a freeze request before a reset?

I want to ensure that other nodes to not get adversely affected when one node resets. As probably part of my issue is that the clock change over on all of the nodes is not 100% synchronous.

0 项奖励
回复