XMC 4200 CAN Bit Timing

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User8620
Level 2
Level 2
Hi,

I am trying to configure the CAN Module of my XMC4200.

I followed the MutliCAN application note. In my main function I send a message every 100ms.
My ECU is connected to a PCAN Usb dongle.

Now the problem:
I can only receive error frames. (stoff error, other errors).
The bit timing must be the problem.
This is what my bit timing config looks like:

XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg=
{
.can_frequency = CAN_FREQUENCY_80, // fCAN=80MHz
.baudrate = (1000 * 500), // baudrate=500K
.sample_point = (8000), // Sample point=80%
.sjw = 2 // SJW=1+1
};


In the CAN Init function I call the XMC function: XMC_CAN_NODE_NominalBitTimeConfigure(CAN_NODE1, &CanBaud_cfg);

Per brute force in noticed that with the following bit timing config, I can receive messages, but there are still many errors:

XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg=
{
.can_frequency = 65000000, // fCAN=120MHz
.baudrate = (1000 * 500), // baudrate=1000K
.sample_point = (10000), // Sample point=87,5%
.sjw = 1 // SJW=1+1
};

The strange thing is that my Global CAN Node is initialized to 80Mhz. How is this possible? I need a bit timing where I have no error frames.
0 Likes
8 Replies
DRubeša
Employee
Employee
First solution authored First like received
Hi oliver.blasius,

can you please tell me are you using XMCLib functions or are working with MULTICAN DAVE APP? From your post I would assume that you´re using XMCLibs while you call "XMC_CAN_NODE_NominalBitTimeConfigure" function but at the end you mention Global CAN Node and that´s part of MULTICAN/CAN_NODE initialization. So can you please clarify this for me and I will have better idea what to suggest you 🙂 Also if it´s not a problem, can you please post your code here...there may be some other issues not related to baudrate setup.

Best regards,
Deni
0 Likes
User8620
Level 2
Level 2
I am using the XMC Library.

This is my Init function and more:


#define CAN_NODE1_TX P2_7
#define CAN_NODE1_RX P2_6
#define CAN_NODE0_TX P1_4
#define CAN_NODE0_RX P1_5

/*
* This is not working: Only error frames
*
*/
//XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg=
//{
// .can_frequency = CAN_FREQUENCY_80, // fCAN=120MHz
// .baudrate = (1000 * 500), // baudrate=1000K
// .sample_point = (8750), // Sample point=87,5%
// .sjw = 2 // SJW=1+1
//};


// with this I am able to receive messages, but also many error frames:

XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg =
{ .can_frequency = 64925000, // fCAN=80MHz
.baudrate = (1000 * 500), // baudrate=500K
.sample_point = (9999), // Sample point=87,5%
.sjw = 1 // SJW=1+1
};

/*
*
*
*/
XMC_CAN_MO_t userSW1_MO8 =
{ .can_mo_type = XMC_CAN_MO_TYPE_TRANSMSGOBJ, .can_id_mode =
XMC_CAN_FRAME_TYPE_STANDARD_11BITS, .can_priority =
XMC_CAN_ARBITRATION_MODE_ORDER_BASED_PRIO_1, .can_identifier =
(uint32_t) 0x111, .can_id_mask = (uint32_t) 0x7ff, .can_ide_mask = 1U,
.can_mo_ptr = (CAN_MO_TypeDef*) CAN_MO8, .can_data_length = (uint8_t) 8,
.can_data[1] = 0x88888888, .can_data[0] = 0x88888888 };

/*
*
*
*/
void CAN_init()
{

//release MultiCAN module via PRSTAT1,
//Configuration of CAN clock:
//registers: CAN->CLC and CAN->FDR, fcan=80Mhz
XMC_CAN_Init((CAN_GLOBAL_TypeDef*)CAN, CAN_FREQUENCY_80);

// CAN node configuration and message object configuration

XMC_CAN_NODE_NominalBitTimeConfigure(CAN_NODE1, &CanBaud_cfg);

XMC_CAN_NODE_EnableConfigurationChange(CAN_NODE1);


XMC_GPIO_SetMode(CAN_NODE1_RX, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_GPIO_SetMode(CAN_NODE1_TX, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);

XMC_CAN_NODE_DisableLoopBack(CAN_NODE1);

//Configuration of the CAN Message Object List Structure:
XMC_CAN_AllocateMOtoNodeList((CAN_GLOBAL_TypeDef*) CAN, 1, 8);

//Configuration of the CAN Message Objects:
XMC_CAN_MO_Config(&userSW1_MO8);

//Start the CAN Nodes:
XMC_CAN_NODE_DisableConfigurationChange(CAN_NODE1);
XMC_CAN_NODE_ResetInitBit(CAN_NODE1);

XMC_CAN_NODE_Enable(CAN_NODE1);
}
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
One more question then 🙂

Are you using CPU Board XMC4200 Actuator board or are you´re using the standalone XMC4200 microcontroller connected to a CAN transceiver?

Best regards,
Deni
0 Likes
User8620
Level 2
Level 2
I am using an own board. (Microcontroller with CAN transciever)

But I also have an evaluation board here.I did not get the CAN to work for the evaluation board, though. (Didnt try really long)
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
So here are some suggestion to try on your board first...if that doesn´t work then please try on your evaluation board also the code that I provide here so we´re sure that firmware is the only issue.

First some ideas to try for your current board:


#define CAN_NODE1_TX P2_7
#define CAN_NODE1_RX P2_6
#define CAN_NODE0_TX P1_5 // <<-- changed pin assignments...check P.S
#define CAN_NODE0_RX P1_4

/*
* This is not working: Only error frames
*
*/
//XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg=
//{
// .can_frequency = CAN_FREQUENCY_80, // fCAN=120MHz
// .baudrate = (1000 * 500), // baudrate=1000K
// .sample_point = (8750), // Sample point=87,5%
// .sjw = 2 // SJW=1+1
//};


// with this I am able to receive messages, but also many error frames:

XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg =
{ .can_frequency = 64925000, // fCAN=80MHz
.baudrate = (1000 * 500), // baudrate=500K
.sample_point = (9999), // Sample point=87,5%
.sjw = 1 // SJW=1+1
};

/*
*
*
*/
XMC_CAN_MO_t userSW1_MO8 =
{ .can_mo_type = XMC_CAN_MO_TYPE_TRANSMSGOBJ, .can_id_mode =
XMC_CAN_FRAME_TYPE_STANDARD_11BITS, .can_priority =
XMC_CAN_ARBITRATION_MODE_ORDER_BASED_PRIO_1, .can_identifier =
(uint32_t) 0x111, .can_id_mask = (uint32_t) 0x7ff, .can_ide_mask = 1U,
.can_mo_ptr = (CAN_MO_TypeDef*) CAN_MO8, .can_data_length = (uint8_t) 8,
.can_data[1] = 0x88888888, .can_data[0] = 0x88888888 };

/*
*
*
*/
void CAN_init()
{

//release MultiCAN module via PRSTAT1,
//Configuration of CAN clock:
//registers: CAN->CLC and CAN->FDR, fcan=80Mhz
XMC_CAN_Init((CAN_GLOBAL_TypeDef*)CAN, CAN_FREQUENCY_80);

// CAN node configuration and message object configuration

XMC_CAN_NODE_NominalBitTimeConfigure(CAN_NODE1, &CanBaud_cfg);

XMC_CAN_NODE_EnableConfigurationChange(CAN_NODE1);
XMC_CAN_NODE_SetInitBit(CAN_NODE1); // <<--- I know it´s not necessary but to be sure that we´re really in Initialization mode

XMC_GPIO_SetMode(CAN_NODE1_RX, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_GPIO_SetMode(CAN_NODE1_TX, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetOutputLevel(CAN_NODE1_TX, XMC_GPIO_OUTPUT_LEVEL_HIGH); // <<--- We want to be sure that TX pin is set high (that recessive state for CAN protocol)

XMC_CAN_NODE_SetReceiveInput(CAN_NODE1, XMC_CAN_NODE_RECEIVE_INPUT_RXDCA); // <<-- Again, it´s good practice to set the input channel while if you´re going to change the node you use this will remind you to change the input appropriately

XMC_CAN_NODE_DisableLoopBack(CAN_NODE1);

//Configuration of the CAN Message Object List Structure:
XMC_CAN_AllocateMOtoNodeList((CAN_GLOBAL_TypeDef*) CAN, 1, 8);

//Configuration of the CAN Message Objects:
XMC_CAN_MO_Config(&userSW1_MO8);

//Start the CAN Nodes:
XMC_CAN_NODE_DisableConfigurationChange(CAN_NODE1);
XMC_CAN_NODE_ResetInitBit(CAN_NODE1);

XMC_CAN_NODE_Enable(CAN_NODE1);
}


And if that doesn´t work try to see if the following initialization code runs on XMC4200 evaluation board:



#define CAN_NODE0_TX P1_5 // <<-- only these pins should be used while they´re connected to the CAN transceiver which is located on the evaluation board
#define CAN_NODE0_RX P1_4 // <<-- changed pin assignments...check P.S


XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg=
{
.can_frequency = CAN_FREQUENCY_80, // fCAN=120MHz
.baudrate = (1000 * 500), // baudrate=1000K
.sample_point = (8750), // Sample point=87,5%
.sjw = 1 // SJW= 1
};



XMC_CAN_MO_t userSW1_MO8 =
{ .can_mo_type = XMC_CAN_MO_TYPE_TRANSMSGOBJ, .can_id_mode =
XMC_CAN_FRAME_TYPE_STANDARD_11BITS, .can_priority =
XMC_CAN_ARBITRATION_MODE_ORDER_BASED_PRIO_1, .can_identifier =
(uint32_t) 0x111, .can_id_mask = (uint32_t) 0x7ff, .can_ide_mask = 1U,
.can_mo_ptr = (CAN_MO_TypeDef*) CAN_MO8, .can_data_length = (uint8_t) 8,
.can_data[1] = 0x88888888, .can_data[0] = 0x88888888 };

/*
*
*
*/
void CAN_init()
{

//release MultiCAN module via PRSTAT1,
//Configuration of CAN clock:
//registers: CAN->CLC and CAN->FDR, fcan=80Mhz
XMC_CAN_Init((CAN_GLOBAL_TypeDef*)CAN, CAN_FREQUENCY_80);

// CAN node configuration and message object configuration

XMC_CAN_NODE_NominalBitTimeConfigure(CAN_NODE0, &CanBaud_cfg); // <<-- Previously mentioned pins are only available for NODE0 so NODE0 should be used

XMC_CAN_NODE_EnableConfigurationChange(CAN_NODE0);
XMC_CAN_NODE_SetInitBit(CAN_NODE0);

XMC_GPIO_SetMode(CAN_NODE0_RX, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_GPIO_SetMode(CAN_NODE0_TX, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1); // <<-- Different alternative function is used
XMC_GPIO_SetOutputLevel(CAN_NODE0_TX, XMC_GPIO_OUTPUT_LEVEL_HIGH);

XMC_CAN_NODE_SetReceiveInput(CAN_NODE0, XMC_CAN_NODE_RECEIVE_INPUT_RXDCD); // <<-- Different input receive channel is used

XMC_CAN_NODE_DisableLoopBack(CAN_NODE0);

//Configuration of the CAN Message Object List Structure:
XMC_CAN_AllocateMOtoNodeList((CAN_GLOBAL_TypeDef*) CAN, 0, 8); // <<-- Different node is used

//Configuration of the CAN Message Objects:
XMC_CAN_MO_Config(&userSW1_MO8);

//Start the CAN Nodes:
XMC_CAN_NODE_DisableConfigurationChange(CAN_NODE0);
XMC_CAN_NODE_ResetInitBit(CAN_NODE0);

XMC_CAN_NODE_Enable(CAN_NODE0);


Try my suggestions and let me know how it went 😉

P.S I also noticed that you switched TX and RX pin for NODE0...so CAN_TX = P1.5 and CAN_RX = P1.4

Best regards,
Deni
0 Likes
User8620
Level 2
Level 2
Ok I think we figured out the problem:

The communication works without errors when we use the following config:

XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t CanBaud_cfg =
{
.can_frequency = CAN_FREQUENCY_80, // fCAN=80MHz
.baudrate = (1000 * 370), // baudrate=500K
.sample_point = (8000), // Sample point=87,5%
.sjw = 1 // SJW=1+1
};

The baud rate is set to 370k, but the actual baud rate is 500k.

There must be a problem with the peripheral clock, because we have the same problem wit the UART connection:
There we want to send with 250k, but we must initialize the baudrate to 189k

Do we have to call some addintional Clock API functions? In our code we do not initialize clocks. I thought clock initializitation is done in the SystemSetup function, before the main Function.

What should we do to have the correct clock settings?


Edit:
OK solved the problem. Our externel clock source was 16Mhz. The standart configuration is always 12Mhz.
I wrote an own SystemCoreClockSetup function, where I call the XMC_SCU_Init function. The comunication works now with the correct baudrate.
0 Likes
Not applicable
Hello, guys.
I'm happy that you've solved your problem, discussed in this thread.

I have another question about XMC4200 bit timing.
How can I switch it on the fly, specially, if my hardware is already initialized by DAVE's init functions.
Namely, I need to reinit my CANs from 83333 to 500000.
Here is my code, which does not work:
void CANxUpdateBaudrate( const CAN_NODE_t* handle, uint32_t baudrate )
{
//Disable CAN node participation in CAN traffic
XMC_CAN_NODE_SetInitBit(handle->node_ptr);
//Function to configure the baud rate based on UI configuration
//Keep sample_point and sjw as they was before, update baudrate.
CAN_NODE_ConfigBaudrate(handle, baudrate, handle->baudrate_config->sample_point, handle->baudrate_config->sjw);
//Enable CAN node participation in CAN traffic
XMC_CAN_NODE_ResetInitBit(handle->node_ptr);
}


This is usage example:
CANxUpdateBaudrate( &CAN1, 500000 );


NOTE: my CANs works fine at 83333, I have to update
  CAN1_BitTimeConfig.baudrate = 83333;
CAN2_BitTimeConfig.baudrate = 83333;

in main.c before DAVE_Init(), because GUI does not allow to set CAN's baudrate less than 100k.


Now the method, which I use to check how it works:
I add 2 MOs on my CANs: CAN1, CAN2, one for receive and transmit respectively.
Then I add Rx and Tx events on needed MOs and link them to corresponding INTERRUPTs.
When I do so, and enable these INTERRUPTs, they start to occur and receive CAN frames as I expect.

This works fine with settings inited by GUI both at 83333 and 500000 bauds.
But do not work when I try to switch baudrate. At least INTERRUPTs do not occurs.


Sorry for using this thread for additional question. If it is better to start new thread let me know.
0 Likes
Not applicable
UPDATE: Posted new thread.
0 Likes