XMC4300 Relax CAN_NODE0 pin allocation issue in Dave4

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

cross mob
Not applicable
According to the XMC4300 Relax documentation, and a continuity check, the can xcvr is connected to:

CAN_RXD (pin 28) P14_3
CAN_TXD (pin 52) P2_0

The DAVE APP manual pin allocator does not list Port 2.0 as a TX port option. Anyone have ideas how to make it work?

To get here I have created a new project, added a Dave APP Can_Node_0. Configured it to 500k without loopback. Then going to the manual pin allocator I have the needed RXD port, but TXD offers:
#2(P0.0) Arduino_UART_RX
#75(P1.4) ECAT0.P0_RXD0A
#5 (P3.2) ECAT0.P1_TXD1

None of these are the ports connected to the Can Xcvr, so they're not going to do me much good.

I have also tried editing the code from the Simple Can transmission thread by Turbofish without much success. I get no output on the CAN analyzer.

Can.h
#ifndef _CAN_H_DEFINED_
#define _CAN_H_DEFINED_

#include "xmc_can.h"
#include "xmc_gpio.h"

#define CAN_PIN_TX P2_0
#define CAN_PIN_RX P14_3
#define CAN_FREQUENCY 24000000U
#define CAN_BAUDRATE 500
#define CAN_SAMPLE_POINT 80
#define CAN_SJW 2
#define CAN_CFG_NODE CAN_NODE0
#define CAN_CFG_NODE_NUM 0
#define CAN_CFG_MO_LIST_SIZE 8

void can_init(void);
void can_send(uint32_t id, uint8_t* data, size_t length);

#endif /* _CAN_H_DEFINED_ */



can.c
#include "can.h"

XMC_CAN_MO_t _can_tx_msg = {
.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(void) {
/*
* Baud-rate configuration
*/
XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t can_baud_cfg = {
.can_frequency = CAN_FREQUENCY,
.baudrate = (CAN_BAUDRATE * 1000),
.sample_point = (CAN_SAMPLE_POINT * 100),
.sjw = CAN_SJW
};

/* Set CAN_PIN_TX to alternative 1 mode (CAN_TXD) */
XMC_GPIO_SetMode(CAN_PIN_TX, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1); //alt1= CAN.N0_TXD on 2_0 pg23-37

/* Set CAN_PIN_RX to input tristate */
XMC_GPIO_SetMode(CAN_PIN_RX, XMC_GPIO_MODE_INPUT_TRISTATE);

/* Set CAN_PIN_RX to digital input */
XMC_GPIO_EnableDigitalInput(CAN_PIN_RX);

/* Initialize CAN global registers with the correct frequency */
XMC_CAN_Init((CAN_GLOBAL_TypeDef*)CAN, XMC_CAN_CANCLKSRC_FPERI, CAN_FREQUENCY); //too few parameters, needs XMC_CAN_CANCLKSRC_t, but shouldn't?

/* Configure the baud-rate */
XMC_CAN_NODE_NominalBitTimeConfigure(CAN_CFG_NODE, &can_baud_cfg);

/* Allow configuration change */
XMC_CAN_NODE_EnableConfigurationChange(CAN_CFG_NODE);

/* Set init bit, shut down node */
XMC_CAN_NODE_SetInitBit(CAN_CFG_NODE);

/* Set the input pin (RX) */
XMC_CAN_NODE_SetReceiveInput(CAN_CFG_NODE, XMC_CAN_NODE_RECEIVE_INPUT_RXDCB); //CAN.N0_RXDB pg23-38

/* Allocate list */
XMC_CAN_AllocateMOtoNodeList((CAN_GLOBAL_TypeDef*)CAN, CAN_CFG_NODE_NUM, CAN_CFG_MO_LIST_SIZE);
XMC_CAN_MO_Config(&_can_tx_msg);

/* No further configuration is allowed */
XMC_CAN_NODE_DisableConfigurationChange(CAN_CFG_NODE);

/* Reset init bit */
XMC_CAN_NODE_ResetInitBit(CAN_CFG_NODE);

}

/***************************************************************************/
void can_send(uint32_t id, uint8_t* data, size_t length) {
int i;

/* Set length and id */
_can_tx_msg.can_data_length = length;
_can_tx_msg.can_identifier = id;

/* Copy data */
for(i=0; i _can_tx_msg.can_data_byte = data;

XMC_CAN_MO_UpdateData(&_can_tx_msg);
XMC_CAN_MO_Transmit(&_can_tx_msg);
}




main.c
#include "XMC4300.h"
#include "System_XMC4300.h"
#include "xmc_common.h"
#include "can.h"


#define TOGGLE07 P0_7 //Logic analyzer
#define TOGGLE09 P0_9 //Logic analyzer
#define P_LED1 P4_0 //visual check
#define P_LED2 P4_1


void delay(uint32_t i) {
while (i--) {
__asm("nop");
}
}

void Init_LED_LA ()
{
/* Set mode of all LED/Analyzer ports to push-pull and output level to low*/
XMC_GPIO_SetMode(P_LED1, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetOutputHigh(P_LED1);
XMC_GPIO_SetMode(P_LED2, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetOutputHigh(P_LED2);
XMC_GPIO_SetMode(TOGGLE07, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetOutputHigh(TOGGLE07);
XMC_GPIO_SetMode(TOGGLE09, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetOutputHigh(TOGGLE09);
}

void XMC_AssertHandler(const char *const msg, const char *const file, uint32_t line) {
/* Break here */
__asm("nop");
}

int main(void)
{



uint8_t data[8] = { 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55 };

SystemInit();
SystemCoreSetup();
SystemCoreClockSetup();
SystemCoreClockUpdate();
Init_LED_LA();

XMC_GPIO_SetOutputLevel(P_LED1, 1);
XMC_GPIO_SetOutputLevel(TOGGLE07, 1);
delay(CAN_FREQUENCY/100);

XMC_GPIO_SetOutputLevel(P_LED1, 0);
XMC_GPIO_SetOutputLevel(TOGGLE07, 0);
delay(CAN_FREQUENCY/100);

can_init();

XMC_GPIO_SetOutputLevel(P_LED1, 1);
XMC_GPIO_SetOutputLevel(TOGGLE07, 1);
delay(CAN_FREQUENCY/10);

while(1) {
delay(CAN_FREQUENCY);

/* Send some data with id 0x111 */

can_send(0x111, data, sizeof(data));
XMC_GPIO_ToggleOutput(P_LED2);
XMC_GPIO_ToggleOutput(TOGGLE09);
delay(CAN_FREQUENCY/10);
}

return 0;
}



Any pointers on either approach would be great, I'm lost.

Edit: This all works great now on the XMC4300, I have edited in the new code so the next guy struggling can have an answer.
0 Likes
1 Reply
DRubeša
Employee
Employee
First solution authored First like received
There are a lot of information and questions in your post, so I will try to provide answers to all of them 🙂

I can confirm that DAVE pin allocation currently does not offer pin 2.0 as a CAN TX pin. The colleagues are informed and we will find fix it as soon as possible.

Referring to the second part of your post (simple CAN transmission example using LLD), as you mentioned you took the example from another forum member. This example was done for XMC4500 Relax kit, and while it seems that only change of include files is sufficient, devil is in details 😛

1. I saw that you noticed that for XMC4300 "XMC_CAN_Init()" function expects 3 parameters. This is true while XMC4300/4700/4800 have the MultiCAN+ module which has an option to use either peripheral clock as a clock source for CAN or external high precision oscillator. XMC4500 uses MultiCAN module (notice lack of "+"), so different function call is necessary.

2. In the example that you copied and modified, pins P1.8 and P1.9 are used as a CAN TX and RX pins. In your case you need to use P14.3 as an input pin. The problem is that port 14 (and 15) is analog port, so if you need to use it as a digital input pin, you need to specify that. Just add additional function call:

"XMC_GPIO_EnableDigitalInput(CAN_PIN_RX);"

right after you set CAN_PIN_RX to input tristate, and everything should be fine.

One more tip, I would suggest you to check and use function "XMC_GPIO_Init()". By using this function you will avoid forgetting things like enable digital pin for ports 14/15, while the function checks that for you. Also, it not necessary to call several functions like "XMC_GPIO_SetMode()", "XMC_GPIO_SetOutputLevel()", while function "XMC_GPIO_Init()" does everything what is necessary.

If you have any additional questions, please feel free to ask 🙂
0 Likes