FlexCAN for MCF52235EVB

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

FlexCAN for MCF52235EVB

1,628 Views
Troublemaker
Contributor II

Hi everyone,

 

I have some problem in MCF52235EVB's FlexCAN. Would you please give me some help.Thanks.

 

The problem is that when I put the FlexCAN in LPB model it will work normally,but When put it in

normally model to send a data it will never be succeed. The registers' state and my code of FlexCAN

is in the attach file.

 

 

Best Begards.

Zhao

Original Attachment has been moved to: 01129640079087_ColdFire_Lite_EVB.zip

Labels (1)
9 Replies

886 Views
TomE
Specialist II

Works in Loopback but not otherwise.

I follow a CAN-specific forum and it seems like half the questions on that forum are from people having this identical problem.

And the reason is that you can't TRANSMIT a packet on CAN unless there's another device on the bus ready to RECEIVE it. Or at least ready to send the "ACK" bit to tell the sender the packet was sent properly.

If you read the description of the Loopback Bit it says why that is working for you:

In this mode, FlexCAN ignores the bit sent during the ACK slot in the CAN frame

acknowledge field, generating an internal acknowledge bit to ensure proper reception of its own message.


Your CAN Registers (and why take bitmap screenshots and then paste them into an Excel Spreadsheet and then attach that??) show the error status ERRSTAT = 0x2252. If you read the Data Sheet that decodes as:

0x2000: Acknowledge error. Indicates whether an acknowledgment

             has been correctly received for a transmitted message.

0x0200: Transmit error status flag. Reflects the status of the FlexCAN

             transmit error counter.

If you read the description of the Loopback Bit it contains:

You have to have another device on the bus for it to work.

Tom


886 Views
Troublemaker
Contributor II

Dear Tom

Thanks for your helpful answer.

>>>>take bitmap screenshots and then paste them into an Excel Spreadsheet and then attach that??

        I just want to let the pepole like you want to help you see the registers clearly and check the setting of

        the registers is wrong or not for me.:smileysilly:

Base on your answer ,is that means I should connect another device to the FlexCAN to send the "ACK" bit

to tell  my MCF52235EVB the packet was sent properly ? If do like this the Acknowledge error or Transmit error status flag will not turn out and a packet will send out successflly.

By the way in my code I set the CANCTRL = 0x49250005 .Is that right if I want set the FlexCAN buadrate to 500k?

Eagerly waiting for your help :smileycry:

Best Regards.

Zhao

0 Kudos

886 Views
TomE
Specialist II

> I just want to let the pepole like you want to help you see the registers clearly

You could have pasted the pictures in without putting them inside a spreadsheet. A spreadsheet is a very weird "envelope" (but I've seen someone at a Japanese Auto Company take an alt-screen-print of a web page showing on a browser, paste that into an Excel Spreadsheet and email that INSTEAD OF JUST SENDING THE URL! :-).

> Base on your answer...

Yes. There must be at least two working devices on the bus. Otherwise you can use Loopback as you have done.

> By the way in my code I set the CANCTRL = 0x49250005

I have no idea as I don't know your crystal frequency is. I'm just reading the MCF52235 Reference Manual the same as you should be doing.

0x49250005 is:

PRESDIV=0x49 = 73 so you're dividing a clock by 74.

RJW=0, PSEG1=4, PSEG2=5, PROPSEG=5, so you're using Rjw=1, Propseg=6 Pseg1=5, Pseg2=6 for a total of Syn+6+5+6=18 bits.

CLK_SRC=0, which is the EXTAL.

You should set RJW higher than that. Read up some App Notes until you understand why.

If this is working at 500,000 Baud with 18 quanta per bit, your master oscillator must be running at 500000*18*74=666,000,000, and that's the CRYSTAL frequency and not the internal oscillator!

So I don't think you've done the maths properly. My working above together with the crystal or oscillator frequency should help you get the right number.

Please do not post any more questions on this until you've read section "30.3.18 Protocol Timing" multiple times, worked through the maths, programmed the chip and then MEASURED the resulting bit rate with an oscilloscope. If you're having problems after that then post all your settings and measurements with any follow-up questions.

If you can't get an exact division from your crystal to 500k then you have to change the number of quanta per bit. For instance you can't get from 16MHz to 500k with 18 quanta per bit, you'd have to change it to 16 and then set PRESDIV to "1" to divide by 2, or some other combination.

I haven't found a "good book" that describes everything you need to know about CAN. I'd suggest starting off from here:

CAN bus - Wikipedia, the free encyclopedia

Follow the External Links. Download and read the original Bosch specification a few times.

Go to Microchip's web site and download AN754. It gives a good introduction to the segments, timing and the quanta.

Tom

0 Kudos

886 Views
Troublemaker
Contributor II

Dear Tom

Would you please answer the question below for me? Thanks.

Actually I use the MCF52235EVB to develop a tool what needs the EPHY work meanwhile the FlexCAN works at 16tq with baudtate 500k.

But there is a problem, the The EPHY requires a 25-MHz crystal for its basic operation as it said in the MCF52235RM.

As a result when I use a 25-MHz crystal the EPHY can work,but the FlexCAN can not be set to 16tq baudtate at 500k.

So what can I do if I want to set the FlexCAN  to 16tq baudtate at 500k at the same time make sure the EPHY works?

Could I change the crystal to 8-MHz for the EPHY?

Is there a method that can make the MCF52235EVB to supply module clock separately to the EPHY and FlexCAN?

By the way why the EPHY requires a 25-MHz crystal for its basic operation?  And why the clock is odd?

I think it is very hard to use for this.


Best Regards

ZHAO

0 Kudos

886 Views
TomE
Specialist II

> By the way why the EPHY requires a 25-MHz crystal


Because it does. Because that's the way Freescale designed it.


> As a result when I use a 25-MHz crystal the EPHY can work,

> but the FlexCAN can not be set to 16tq baudtate at 500k.


Correct. Read through Marks post. He tells you how to do this (or gives enough hints so you should be able to work it out).


Tom


0 Kudos

886 Views
mjbcswitzerland
Specialist V

Hi

Using the 25MHz crystal (recommended due to lowest jitter) I think that CANCTRL = 0x01bf0007 is suitable for 500kHz CAN speed.

This looks to be CAN compliant with Time Segment 1 at 16, Time Segment 2 at 8 and re-synchronisation jump width of 3 (See table 30-15 in the M5223x User's Manual). It uses 12.5MHz Time Quanta clock (divided by 25 in total for 500kHz).

Regards

Mark

0 Kudos

886 Views
Troublemaker
Contributor II

Dear Mark

Thanks.If I set the FlexCAN do 500kHz CAN speed 25tq by the CANCTRL = 0x01bf0007 as you said above, Is the FlexCAN able to communicate with a CAN node that works at 16tq baudtate at 500k? Because in my CAN bus

the other nodes are set like that.

Best Regards

ZHAO

0 Kudos

886 Views
mjbcswitzerland
Specialist V

Hi

I don't know whether the number of Time Quanta a node is actually using is of much relevance. The higher the numebr (max. 25), the better the timing resolution that can be achieved at the node, so using 25 Time Quanta should even allow a bit of tuning.

According to the CAN specification, as depicted in the table in the User's Manual, the setting above should be conform and so match with any other node that is conform, whatever Time Quanta that node is using to generate its own internal timing.

Regards

Mark

0 Kudos

886 Views
mjbcswitzerland
Specialist V

Hi

In oder to get a decent CAN setup I have been using the following (Coldfire and Kinetis):

CANCTRL = fnOptimalCAN_clock(pars->usMode, pars->ulSpeed);

where

// The best choice of clock input is from the external crystal (lowest jitter), however this may not always enable the best settings to achieve the required speed.

// The choice of clock source is user-defined but this routine tries to achieve best settings using highest time quanta resolution.

//

// There are up to 25 time quanta in a CAN bit time and the bit frequency is equal to the clock frequency divided by the quanta number (8..25 time quanta range)

// There is always a single time quanta at the start of a bit period called the SYNC_SEG which can not be changed (transitions are expected to occur on the bus during this period)

// The sampling occurs after time segment 1, which is made up of a propagation segment (1..8 time quanta) plus a phase buffer segment 1 (1..8 time quanta),

// followed by time segment 2, made up of phase buffer segment 2 (2..8 time quanta)

//

// CAN standard compliant bit segment settings give the following ranges (re-synchronisation jump width of 2 is used since it is complient with all))

// Time segment 1 should be 5..10 when time segment 2 is 2 (min/max time quanta per bit is 8/13)

// Time segment 1 should be 4..11 when time segment 2 is 3 (min/max time quanta per bit is 8/15)

// Time segment 1 should be 5..12 when time segment 2 is 4 (min/max time quanta per bit is 10/17)

// Time segment 1 should be 6..13 when time segment 2 is 5 (min/max time quanta per bit is 12/19)

// Time segment 1 should be 7..14 when time segment 2 is 6 (min/max time quanta per bit is 14/21)

// Time segment 1 should be 8..15 when time segment 2 is 7 (min/max time quanta per bit is 16/23)

// Time segment 1 should be 9..16 when time segment 2 is 8 (min/max time quanta per bit is 18/25)

//

static unsigned long fnOptimalCAN_clock(unsigned short usMode, unsigned long ulSpeed) // {156}

{

    unsigned long ulClockSourceFlag = EXTAL_CLK_SOURCE;

    unsigned long ulClockSpeed;

    unsigned long ulLowestError = 0xffffffff;

    unsigned long ulCanSpeed;

    unsigned long ulError;

    unsigned long ulPrescaler;

    int iTimeQuanta = 25;                                                // highest value for highest control resolution

    int iBestTimeQuanta = 25;

    unsigned long ulBestPrescaler;

    if (CAN_USER_SETTINGS & usMode) {

        return ulSpeed;                                                  // the user is passing optimal configuration settings directly

    }

    if (CAN_PLL_CLOCK & usMode) {

        ulClockSpeed = (BUS_CLOCK / 2);

        ulClockSourceFlag = CLK_SRC_INT_BUS;

    }

    else {

        ulClockSpeed = CRYSTAL_FREQ;

    }

    while (iTimeQuanta >= 8) {                                          // test for best time quanta

        ulCanSpeed = (ulClockSpeed/iTimeQuanta);                        // speed without prescaler

        ulPrescaler = ((ulCanSpeed + (ulSpeed/2))/ulSpeed);              // best prescale value

        if (ulPrescaler > 256) {

            ulPrescaler = 256;                                          // maximum possible prescale divider

        }

        ulCanSpeed /= ulPrescaler;

        if (ulCanSpeed >= ulSpeed) {                                    // determine the absolute error value with this quanta setting

            ulError = (ulCanSpeed - ulSpeed);

        }

        else {

            ulError = (ulSpeed - ulCanSpeed);

        }

        if (ulError < ulLowestError) {                                  // if this is an improvement

            ulLowestError = ulError;

            iBestTimeQuanta = iTimeQuanta;                              // best time quanta value

            ulBestPrescaler = ulPrescaler;

        }

        iTimeQuanta--;

    }

    ulBestPrescaler--;

    ulBestPrescaler <<= 24;                                              // move the prescale value into position

    if (iBestTimeQuanta >= 18) {                                        // determine the phase buffer length value

        ulBestPrescaler |= PHASE_BUF_SEG2_LEN8;

        iBestTimeQuanta -= (8 + 1);                                      // remaining time quanta (time segment 1) after removal of the time segment 2 and the SYN_SEG

    }

    else if (iBestTimeQuanta >= 16) {

        ulBestPrescaler |= PHASE_BUF_SEG2_LEN7;

        iBestTimeQuanta -= (7 + 1);

    }

    else if (iBestTimeQuanta >= 14) {

        ulBestPrescaler |= PHASE_BUF_SEG2_LEN6;

        iBestTimeQuanta -= (6 + 1);

    }

    else if (iBestTimeQuanta >= 12) {

        ulBestPrescaler |= PHASE_BUF_SEG2_LEN5;

        iBestTimeQuanta -= (5 + 1);

    }

    else if (iBestTimeQuanta >= 10) {

        ulBestPrescaler |= PHASE_BUF_SEG2_LEN4;

        iBestTimeQuanta -= (4 + 1);

    }

    else {

        ulBestPrescaler |= PHASE_BUF_SEG2_LEN3;

        iBestTimeQuanta -= (3 + 1);

    }

    if (iBestTimeQuanta & 0x1) {                                        // odd

        iBestTimeQuanta /= 2;                                            // PROP_SEG and PSEG1 to achieve time segment 1

        ulBestPrescaler |= iBestTimeQuanta;                              // set propogation bit time (1 more than phase buffer segment 1)

        iBestTimeQuanta--;

        ulBestPrescaler |= (iBestTimeQuanta << 19);                      // set phase buffer segment 1

    }

    else {                                                              // even

        iBestTimeQuanta /= 2;                                            // PROP_SEG and PSEG1 to achieve time segment 1 and phase buffer segment 1

        iBestTimeQuanta--;

        ulBestPrescaler |= ((iBestTimeQuanta << 19) | (iBestTimeQuanta));// {159} set equal propogation bit times

    }

    return (RJW_2 | ulClockSourceFlag | ulBestPrescaler);                // initialise the CAN controller with the required speed and parameters

}


I found the TOTAL PHASE Kommodo CAN Duo very useful for CAN work and made this video some time ago. It is on a Kinetis (with Dual CAN) but the Coldfire is equivalent:


Regards

Mark

http://www.uTasker.com

0 Kudos