9s12X CAN initialisation

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

9s12X CAN initialisation

Jump to solution
814 Views
dastek
Contributor III


I am trying to set up the CAN interface on my 9s12XEQ384 so that the baud rate is 500 KBaud.  I am using the TJA1040 CAN tranceiver.

My oscillator is a 5.0 MHz device and I am clocking the micro using the PLL at its maximum of 50 MHz.

I have confirmed, using a software loop as well as an ECT routine that the bus clock is 50 MHz.

I have an application that runs on a 9s12DG256 that will generate a CAN message at 500 KBaud, so I have a way of testing my code.

I found an XLS spread sheet (Called CAN_setup.xls) that calculates CANBTR0 and CANBTR1 values

 

I have tried using both oscillator as well as bus clock as clock source and my message is either too long or too short in time.  I would like to use the oscillator clock as the clock source.  The value for BTR0 = 0x80 and BTR1 = 0x25 as predicted by the XLS spreadsheet.  This does not sync with my other units 500 KBaud bus.

 

Can you see what I am doing wrong?

 

Thanks,

Wade

Labels (1)
0 Kudos
1 Solution
651 Views
RadekS
NXP Employee
NXP Employee

Hi Wade,

I cannot see anything significantly wrong in your code.

The nominal bit time is composed of SYNC_SEG, PROP_SEG, PHASE_SEG1 and PHASE_SEG2.

The sampling point is at an edge between PHASE_SEG1 and PHASE_SEG2.

In case of 9s12DG256 it is

1Tq+2Tq+2Tq+3Tq and sampling point is at 62.5% of the nominal bit time.

In case of 9s12XEQ384 it is

1Tq+3Tq+3Tq+3Tq and sampling point is at 70% of nominal bit time.  

Could you please try BTR0_500 = 0xC0 and BTR1_500 = 0x34?

In that case, it should be

1Tq+2Tq+3Tq+4Tq and sampling point is at 60% of nominal bit time which is more close to original sampling point at 9s12DG256.

I hope it helps you.

Have a great day,
Radek

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
3 Replies
651 Views
dastek
Contributor III

9s12XEQ384

Oscilator freq 5.0 MHz
Bus freq 50 MHz


#define BTR0_500 0x80         // Gives 190us for a packet, expected length is 211 us or 202.8us
#define BTR1_500 0x25
#define CTL1 CANE                // To select Oscilator clock = CLKSRC

void CAN0_Dont_care(void)                    // Setup Acceptance registers
{                                                                 // Can only be done in initialization mode !
CAN0IDAR0 = 0xff; CAN0IDAR1 = 0xff; // Acceptance registers [0..7]
CAN0IDAR2 = 0xff; CAN0IDAR3 = 0xff; // Must be done in initialization mode.
CAN0IDMR0 = 0xff; CAN0IDMR1 = 0xff; //
CAN0IDMR2 = 0xff; CAN0IDMR3 = 0xff; // 16 bit filter mode (page 42 of MSCAN V02.14)
CAN0IDAR4 = 0xff; CAN0IDAR5 = 0xff;
CAN0IDAR6 = 0xff; CAN0IDAR7 = 0xff;
CAN0IDMR4 = 0xff; CAN0IDMR5 = 0xff; // DONT_CARE
CAN0IDMR6 = 0xff; CAN0IDMR7 = 0xff;
}

void CAN_Init_UniQ(void) // 9sXEQ384
{
CAN0CTL0 |= INITRQ;                               // set INITRQ, this will also set INITAK

CAN0_Buffer_put = CAN0_Buffer_get =
CAN1_Buffer_put = CAN1_Buffer_get = 0; // Zero index before we initialise CANs

while ((CAN0CTL1 & INITAK) != 1) ;           // wait for init mode to occur
CAN0CTL1 = CTL1;                                     // Set CANE just in case this is the first time after reset
                                                                      // CANE = 1 = CAN Enable, CLKSRC = 0 = Oscilator clock
CAN0BTR0 = BTR0_500;                           
CAN0BTR1 = BTR1_500;                           // CAN_TSEG1 = 0x05

CAN0IDAC = IDAM0;                                 // Four 16 bit acceptance filters

CAN0_Dont_care();                                    // Setup Acceptance registers
CAN0CTL0 &= ~INITRQ;                           // clear INITRQ. Restart and synchronise
while ((CAN0CTL1 & INITAK) != 0) ;           // Wait for acknowledge

CAN0RIER = CSCIE | RSTATE0 | TSTATE0 | OVRIE | RXFIE; // enable receive interrupt RXFIE
CAN0RFLG = WUPIF | OVRIF | RXF;         // Reset Error Flags

}

9s12DG256

Oscilator freq 4.0 MHz
Bus freq 25 MHz

#define CAN_TSEG1 0x03                       // BitRate = fTq / ( Time Quanta)
#define CAN_TSEG2 0x02                       // Time Quanta = (SYNCH_SEG+(CAN_TSEG1+1)+(CAN_TSEG2+1))
#define BAUDRATE_500 1
#define CAN_SJW2 0x01 << 6                 // CAN SJW = 2

void CANInit_UniQ(void)                           // 9sDG256
{
CAN0_Buffer_put = CAN0_Buffer_get =
CAN1_Buffer_put = CAN1_Buffer_get = 0;                    // Zero index before we initialise CANs

CAN0CTL0 |= INITRQ;                                                   // set INITRQ, this will also set INITAK
while ((CAN0CTL1 & INITAK) != 1) ;                              // wait for init mode to occur

CAN0CTL1 = CANE;                                                      // Set CANE just in case this is the first time after reset
// CANE = 1 = CAN Enable, CLKSRC = 0 = Oscilator clock
CAN0BTR0 = CAN_SJW2 | (BAUDRATE_500 - 1);      // 4.0MHz / (0x01 - 1) === 500 kHz
                                                                                          // CAN Baud of 500kbps at 4Mhz crystal (Was 0x43)
CAN0BTR1 = (CAN_TSEG2 << 4) + CAN_TSEG1;     // CAN_TSEG1 = 0x03
                                                                                          // CAN_TSEG2 = 0x02
CAN0IDAC = IDAM0;                                                      // Four 16 bit acceptance filters

CAN0IDAR0 = 0xff; CAN0IDAR1 = 0xff;                        // Acceptance registers [0..7]
CAN0IDAR2 = 0xff; CAN0IDAR3 = 0xff;                        // Must be done in initialization mode.
CAN0IDMR0 = 0xff; CAN0IDMR1 = 0xff;
CAN0IDMR2 = 0xff; CAN0IDMR3 = 0xff;                        // 16 bit filter mode (page 42 of MSCAN V02.14)
CAN0IDAR4 = 0xff; CAN0IDAR5 = 0xff;
CAN0IDAR6 = 0xff; CAN0IDAR7 = 0xff;
CAN0IDMR4 = 0xff; CAN0IDMR5 = 0xff;                          // DONT_CARE
CAN0IDMR6 = 0xff; CAN0IDMR7 = 0xff;

CAN0CTL0 &= ~INITRQ;                                                    // clear INITRQ
while ((CAN0CTL1 & INITAK) != 0) ;                                    // Wait for acknowledge
CAN0RIER = CSCIE | RSTATE0 | TSTATE0 | OVRIE | RXFIE; // enable receive interrupt RXFIE
CAN0RFLG = WUPIF | OVRIF | RXF;                                  // Reset Error Flags

}

We sell thousands of our product a year so I know that the DG256 initialisation must be correct.

The CANH and CANL pins are wired correctly.

Acceptance filter are set to accept all.

Regards,

Wade

0 Kudos
652 Views
RadekS
NXP Employee
NXP Employee

Hi Wade,

I cannot see anything significantly wrong in your code.

The nominal bit time is composed of SYNC_SEG, PROP_SEG, PHASE_SEG1 and PHASE_SEG2.

The sampling point is at an edge between PHASE_SEG1 and PHASE_SEG2.

In case of 9s12DG256 it is

1Tq+2Tq+2Tq+3Tq and sampling point is at 62.5% of the nominal bit time.

In case of 9s12XEQ384 it is

1Tq+3Tq+3Tq+3Tq and sampling point is at 70% of nominal bit time.  

Could you please try BTR0_500 = 0xC0 and BTR1_500 = 0x34?

In that case, it should be

1Tq+2Tq+3Tq+4Tq and sampling point is at 60% of nominal bit time which is more close to original sampling point at 9s12DG256.

I hope it helps you.

Have a great day,
Radek

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
651 Views
RadekS
NXP Employee
NXP Employee

Hi Wade,

Could you please also specify your oscillator frequency, CAN bit time settings and type of CAN transceiver on 9s12DG256 side?

Are you sure that 9s12DG256 clock frequency is OK?

The bus clock might be routed to ECLK(PE4) pin by command ECLKCTL_NECLK=0; also in normal mode.

 

I suppose that CANH, CANL and GND signals are connected correctly and transceivers are both powered and configured. Right?

Do you use the same ground for both MCUs/boards?

 

What are your settings of acceptance filters?

 

Could you please share here your CAN init routine?

I hope it helps you.

Have a great day,
Radek

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos