xmc2go and xmclib for UART in dave 4 ?

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

cross mob
WoS
Employee
Employee
First solution authored
As the xmc2go does not work with the UART app in DAVE v4 yet, I tried an alternate approach using the XMC lib in DAVE v4.
I used "simple main project" and selected the XMC1100 in the VQFN24 package and 64kB flash option.

There is an example in the manual of the lib for the UART using USIC CH1 using some other pins, so I just did some adoption to the mentioned board, as specified in the xmc1100 manual.
I connected P2_1 and P2_2 to USIC CH00 properly using the multiplexers on the GPIO and UART acc. to the I/O table (XMC1100 Reference Manual - Ports - v2.4, page 17-47).
The setup was straight forward and quickly done using the documentation of the XMC lib...

I just had to fix "xmc_uart.h" as I found an issue in an #ifdef in line 161, there was a comparison of:
#if UC_SERIES == XMC1
which can't be really right? So I fixed it to:
#if UC_FAMILY == XMC1
Otherwise I was not able to route the input source to the UART DX3.

The code compiles and runs (the LED toggles once) but I still don't get anything on the TX pin and it does also not react on RX.
Btw, I did also set up some timer to check the timing (also found in the examples) - works nicely, so it seems not to be an issue with some clock setup.
I also did some basic debugging on the code and could not really see an issue as well...

What do I miss here or made wrong?

Thanks in advance! 🙂

---

Just copied all together for this post and simplified a bit for a minimal example which I expected to work:

/* do not use - illustration only, not functional ! */

#include
#include

int main(void) {
const uint8_t message[] = "Hello world!!\n";
uint32_t index;

/* UART configuration */
const XMC_UART_CH_CONFIG_t uart_config = {
.baudrate = 115200,
.data_bits = 8U,
.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE,
.stop_bits = 1U
};

/* Configure UART channel */
XMC_UART_CH_Init(XMC_UART0_CH0, &uart_config);
XMC_UART_CH_SetInputSource(XMC_UART0_CH0, XMC_UART_CH_INPUT_RXD1, USIC0_C0_DX3_P2_2);

/* Start UART channel */
XMC_UART_CH_Start(XMC_UART0_CH0);

/* Configure pins */
XMC_GPIO_SetMode(P2_2, XMC_GPIO_MODE_INPUT_TRISTATE); /* UART RX */
XMC_GPIO_SetMode(P2_1, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT6); /* UART TX */
XMC_GPIO_SetMode(P1_0, XMC_GPIO_MODE_OUTPUT_PUSH_PULL); /* LED */

/* Send some text */
for (index = 0; index < sizeof(message) - 1; index++) {
XMC_UART_CH_Transmit(XMC_UART0_CH0, message[index]);
}

/* toggle LED */
XMC_GPIO_ToggleOutput(P1_0);

/* Loop */
while(1) {
uint16_t val;

/* toggle LED on input as well */
val = XMC_UART_CH_GetReceivedData(XMC_UART0_CH0);
if (val!=0) {
XMC_GPIO_ToggleOutput(P1_0);
}
}
return 0;
}
0 Likes
10 Replies
chismo
Employee
Employee
First like received
Hello,

In the example you provided, it seems that you are looping back the data transmitted on TXD to RXD.
For the transmit path, it looks fine to me so it is strange that you do not see the anything on the TXD line.
Would it be possible to try on alternative output pins or even UART1?

For the receive path, one problem is that the DX3 input cannot be used directly as RXD. For this, only the DX0 can be used.
However, DX3 can be routed to DX0 by additionally enabling the DX0G function with the line:

XMC_UART_CH_SetInputSource(XMC_UART0_CH0, XMC_UART_CH_INPUT_RXD, USIC0_C0_DX0_DX3INS);

Furthermore, to create the loop back, I assume that you are connecting P2.1 and P2.2 externally with a wire.

I hope this helps.

Regards,
Min Wei
0 Likes
WoS
Employee
Employee
First solution authored
Hello and thanks for your quick response!

As mentioned, I am trying to evaluate DAVE v4 and its xmclib with the XMC2go and get something working with it, I have a functional solution in DAVE v3 using its Apps there, so the HW is ok.

I am using the xmc1100 UART connected to the Debugger UART on the eval board. So nothing special here in place, the pin out is given by this board and I can't change it. I don't need a loop back, I have a terminal program running on the PC (via USB serial from the debugger) and I want to see the "Hello world!!" text there and the LED toggling when pressing any key in the terminal program. The example is just the minimal working setup for illustration (something like this is also provided for DAVE v3).

Thank you very much for the hint with the input path, I was aware of this fact, it was just not clear for me how to use it with the xmclib, as the comment on the function in the xmclib states "XMC_UART_CH_INPUT_RXD (for DX0), XMC_UART_CH_INPUT_RXD1 (for DX3), XMC_UART_CH_INPUT_RXD2 (for DX5)".

I replaced the input source configuration as you mentioned - no change, still no reaction on reception, altough valid UART frames are of course provided on P2_2 from the debugger serial channel (seen with oscilloscope when pressing a key in the terminal program).

Furthermore, the UART of the XMC1100 still does not send anything, TX (= P2_1) stays low (checked with oscilloscope). Using ALT6 for the GPIO mode on port P2.1 is correct to get the UART routed there, isn't it ?

So there must be something else missing - is the XMC lib maybe only for XMC1200 and up? At least the examples in the lib package one can download suggests that...

Thanks again for your help,
Wolfgang
0 Likes
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

Pins P2.1 and P2.2 belong to the analog port 2. To use these pins as digital input/output pins, you need to use additionally the function XMC_GPIO_EnableDigitalInput().
Note: In the XMC1 family, meanwhile all pins of port 2 can behave as digital inputs, only some pins of the port 2 can be used as digital output (P2.0, P2.1, P2.10, P2.11). See documentation.

In general, it is better to initialize the pins using the XMC_GPIO_Init since it hides these details.

Best regards,
Jesus
0 Likes
WoS
Employee
Employee
First solution authored
Thanks, got it. Yes, the GPIO mode function in the lib does not handle the analog/digital switching, 😞
XMC_GPIO_Init() is a much cleaner approach as well.


/* (very) simple example for "XMC 2 go" kit, using XMC lib in DAVE v4 */

/* Author: WoS, 7/2015 - reworked from a xmc lib example with help from jferreira and chismo (Infineon xmc forum) */

/* In Dave, use "new project" -> "DAVE project" -> "Simple main project" and replace the
inital content of main.c with this code. Requires terminal program (115200/8/n/1) to run.*/

/* Made for illustration only. Use at your own risk. No guarantees whatsoever. */

#include
#include

int main(void) {
/* UART configuration */
const XMC_UART_CH_CONFIG_t uart_config = {
.baudrate = 115200,
.data_bits = 8U,
.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE,
.stop_bits = 1U
};

/* Configure UART channel, to do this you need to fix the ifdef at line 161 in xmc_uart.h of the XMC peripheral library */
XMC_UART_CH_Init(XMC_UART0_CH0, &uart_config);
XMC_UART_CH_SetInputSource(XMC_UART0_CH0, XMC_UART_CH_INPUT_RXD, USIC0_C0_DX0_DX3INS);
XMC_UART_CH_SetInputSource(XMC_UART0_CH0, XMC_UART_CH_INPUT_RXD1, USIC0_C0_DX3_P2_2);

/* Start UART channel */
XMC_UART_CH_Start(XMC_UART0_CH0);

/* GPIO configuration */
const XMC_GPIO_CONFIG_t p2_2_conf = {
.mode = XMC_GPIO_MODE_INPUT_TRISTATE,
.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD
};
const XMC_GPIO_CONFIG_t p2_1_conf = {
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT6,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH
};
const XMC_GPIO_CONFIG_t p1_0_conf = {
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW
};

/* Configure GPIO, P2 also needs to be set to digital - mode set is not enough */
XMC_GPIO_Init(P2_1,&p2_1_conf); /* UART TX */
XMC_GPIO_Init(P2_2,&p2_2_conf); /* UART RX */
XMC_GPIO_Init(P1_0,&p1_0_conf); /* LED */

/* Send some text */
const uint8_t message[] = "Hello world!!\n";
uint32_t index;
for (index = 0; index < sizeof(message) - 1; index++) {
XMC_UART_CH_Transmit(XMC_UART0_CH0, message[index]);
}

/* Toggle LED (was off after init, now it is on) */
XMC_GPIO_ToggleOutput(P1_0);

/* Wait until receiving key 'A', then toggle LED */
while(1) {
/* read from UART only if possible */
if (XMC_USIC_CH_GetReceiveBufferStatus(XMC_UART0_CH0)) {
uint16_t val;
val = XMC_UART_CH_GetReceivedData(XMC_UART0_CH0);
/* check for specific key */
if (val=='A') {
/* got it, toggle LED */
XMC_GPIO_ToggleOutput(P1_0);
}
}
}

/* Never get here... */
return 0;
}


Thanks again to both of you! 😉
0 Likes
cbg
Employee
Employee
First solution authored First like received
Hi,
I've got the same problem as OP with XMC2Go but I wan't the receiver to work with Interrupts. I can't get it to work with Interrupts but with polling the Frame Receive Finished Flag it works.
Besides, in my xmc_uart.h I had to Change this in order to be able to configure the UART correctly:
/**
* UART Input sampling frequency options
*/
typedef enum XMC_UART_CH_INPUT_SAMPLING_FREQ
{
XMC_UART_CH_INPUT_SAMPLING_FREQ_FPERIPH = XMC_USIC_CH_INPUT_SAMPLING_FREQ_FPERIPH, /**< Sampling frequency input fperiph*/
XMC_UART_CH_INPUT_SAMPLING_FREQ_FRACTIONAL_DIVIDER = XMC_USIC_CH_INPUT_SAMPLING_FREQ_FRACTIONAL_DIVIDER /**< Sampling frequency input fractional divider*/
} XMC_UART_CH_INPUT_SAMPLING_FREQ_t;

/**
* UART input stages
*/
typedef enum XMC_UART_CH_INPUT
{
XMC_UART_CH_INPUT_RXD = 0UL /**< UART input stage DX0*/
// #if UC_SERIES == XMC1 <----- was like this, but for XMC1100 Q024x64 UC_SERIES is defined XMC11, UC_FAMILY is defined XMC1
#if UC_SERIES == XMC11
,
XMC_UART_CH_INPUT_RXD1 = 3UL, /**< UART input stage DX3*/
XMC_UART_CH_INPUT_RXD2 = 5UL /**< UART input stage DX5*/
#endif
} XMC_UART_CH_INPUT_t;


I'm using the Interrupt Handler name listed in my Startup_XMC1100.S, which is USIC0_1_IRQHandler for the IRQ I am using but the handler is never called.
Any hints for me?

Thanks in advance!


#include
#include
#include

#define UART_CH XMC_UART0_CH0
#define RX_Handler USIC0_1_IRQHandler
#define UART_IRQn USIC0_1_IRQn

static void (*rx_callback)(void);

void UART_init(void (*rxcb)(void))
{
rx_callback = rxcb;


/* Pin config */
const XMC_GPIO_CONFIG_t p2_2_conf = {
.mode = XMC_GPIO_MODE_INPUT_TRISTATE,
.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD
};
const XMC_GPIO_CONFIG_t p2_1_conf = {
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT6,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH

};

XMC_GPIO_EnableDigitalInput(P2_2);
XMC_GPIO_EnableDigitalInput(P2_1);
XMC_GPIO_Init(P2_2, &p2_2_conf); /* RxD */
XMC_GPIO_Init(P2_1, &p2_1_conf); /* TxD */

/* UART config */
const XMC_UART_CH_CONFIG_t uart_config = {
.baudrate = 19200,
.data_bits = 8U,
.frame_length = 8U,
.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE,
.stop_bits = 1U,
.oversampling = 16U
};

XMC_UART_CH_Init(UART_CH, &uart_config);
XMC_UART_CH_SetInputSource(UART_CH, XMC_UART_CH_INPUT_RXD, USIC0_C0_DX0_DX3INS);
XMC_UART_CH_SetInputSource(UART_CH, XMC_UART_CH_INPUT_RXD1, USIC0_C0_DX3_P2_2);

/* Both don't work */
XMC_UART_CH_EnableEvent(UART_CH, XMC_UART_CH_EVENT_FRAME_FINISHED);
// XMC_UART_CH_EnableEvent(UART_CH, XMC_UART_CH_EVENT_STANDARD_RECEIVE);

/* Both don't work */
XMC_USIC_CH_SetInterruptNodePointer(UART_CH, XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL, UART_IRQn);
// XMC_USIC_CH_SetInterruptNodePointer(UART_CH, XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, UART_IRQn);

NVIC_SetPriority(UART_IRQn, 3);
NVIC_EnableIRQ(UART_IRQn);

XMC_UART_CH_Start(UART_CH);
}

void RX_Handler(void)
{
if(rx_callback)
rx_callback();
}


void UART_write(const char *msg)
{
while(*msg != '\0') {
XMC_UART_CH_Transmit(UART_CH, (const uint16_t) *msg);
msg++;
}
}
0 Likes
User10215
Level 4
Level 4
First like received
Hi cbg,

as far as I can see this line seems to be wrong:
"XMC_USIC_CH_SetInterruptNodePointer(UART_CH, XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL, UART_IRQn)"

It has to be the line you commented one row after that:
"XMC_USIC_CH_SetInterruptNodePointer(UART_CH, XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, UART_IRQn)"

Also the parameter for that function is wrong. Try replacing the "UART_IRQn" with an "1". For this function the number of the interrupt output line of the channel is required and not the Interrupt number. Hope that helps.

Regards,
Niclas
0 Likes
cbg
Employee
Employee
First solution authored First like received
Hi Niclas,
thanks for the reply. As commented in the code I tried both Interrupt nodes and the corresponding Events but they both don't work.
The UART_IRQn is a define by me which you can see at the top. Should have removed the defines for this post, sorry about that.

#define UART_CH XMC_UART0_CH0
#define RX_Handler USIC0_1_IRQHandler
#define UART_IRQn USIC0_1_IRQn
0 Likes
User10215
Level 4
Level 4
First like received
No , no...the defines are ok.
The "XMC_USIC_CH_SetInterruptNodePointer"-function requires another Parameter. The description of the function in "xmc_usic.h" states that for the last Parameter of that function a value in the range of 0 to 5 is required. The Interrupt-number "UART_IRQn" is larger than that. You need the number of the Interrupt-Output-line of the Usic-module as Parameter which, in your case is "1".

Greetings,
Niclas
0 Likes
WoS
Employee
Employee
First solution authored
When looking at my example (the "main.c" file), just add this before the XMC_UART_CH_Start() line:


/* enable receive interrupt */
XMC_UART_CH_EnableEvent(XMC_UART0_CH0, XMC_UART_CH_EVENT_STANDARD_RECEIVE);
XMC_USIC_CH_SetInterruptNodePointer(XMC_UART0_CH0,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, 1);
NVIC_EnableIRQ(USIC0_1_IRQn);


plus add this function separately


void USIC0_1_IRQHandler(void) {
/* got it, toggle LED */
XMC_GPIO_ToggleOutput(P1_0);
}


--> the LED is toggling when receiving a character (hence the handler is active).

Of course I removed the code from the while(1) {} loop in the main() function waiting for a specific character. I didn't change anything else. It's just to check the handler is working, of course the next step is to do something useful in the handler, use the priorities correctly, etc.


Hope it helps...


/WoS


Btw: I noticed several examples delivered with the "XMC Peripheral Library v1.0" use just a mode set for the pins instead of the XMC_GPIO_Init() function. I'd say for the sake of compatibility with other pins (and to avoid confusion if it is "enough" e.g for P2_x pins etc.) it should be changed. I'll open a change request case in the tracker for this, together with the issue in xmc_uart.h...
0 Likes
cbg
Employee
Employee
First solution authored First like received
Ok, thank's you two. Got it working with Interrupts now. Was the stupid mistake with XMC_USIC_CH_SetInterruptNodePointer as Niclas said.

For a more uniform usage the function could be altered though to accept the IRQ number and then just subtract the offset of the first IRQ (USIC0_0_IRQn=9) in the function body.
0 Likes