XMC4800 Output Pin Initialization with XMC Library

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

cross mob
User9906
Level 2
Level 2

const DIGITAL_IO_t DOUT__ENABLE =
{
.gpio_port = XMC_GPIO_PORT2,
.gpio_pin = 14,
.gpio_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM
},
.hwctrl = XMC_GPIO_HWCTRL_DISABLED
};



void XMC_GPIO_Init(XMC_GPIO_PORT_t *const port, const uint8_t pin, const XMC_GPIO_CONFIG_t *const config)
{
XMC_ASSERT("XMC_GPIO_Init: Invalid port", XMC_GPIO_CHECK_PORT(port));
XMC_ASSERT("XMC_GPIO_Init: Invalid mode", XMC_GPIO_IsModeValid(config->mode));

/* Switch to input */
port->IOCR[pin >> 2U] &= (uint32_t)~(PORT_IOCR_PC_Msk << (PORT_IOCR_PC_Size * (pin & 0x3U)));

/* HW port control is disabled */
port->HWSEL &= ~(uint32_t)((uint32_t)PORT_HWSEL_Msk << ((uint32_t)pin << 1U));


/* Enable digital input */
if (XMC_GPIO_CHECK_ANALOG_PORT(port))
{
port->PDISC &= ~(uint32_t)((uint32_t)0x1U << pin);
}
else
{
if ((config->mode & XMC_GPIO_MODE_OE) != 0)
{
/* If output is enabled */

/* Set output level */
port->OMR = (uint32_t)config->output_level << pin;

/* Set output driver strength */
port->PDR[pin >> 3U] &= (uint32_t)~(PORT_PDR_Msk << ((uint32_t)PORT_PDR_Size * ((uint32_t)pin & 0x7U)));
port->PDR[pin >> 3U] |= (uint32_t)config->output_strength << ((uint32_t)PORT_PDR_Size * ((uint32_t)pin & 0x7U));

port->OMR = (uint32_t)config->output_level << pin; /* <---- ___ADDED THIS FOR TESTING____ */
}
}

/* Set mode */
port->IOCR[pin >> 2U] |= (uint32_t)config->mode << ((uint32_t)PORT_IOCR_PC_Size * ((uint32_t)pin & 0x3U));
}



void DIGITAL_IO_Init(const DIGITAL_IO_t *const handler)
{
XMC_GPIO_Init(handler->gpio_port, handler->gpio_pin, &handler->gpio_config);
XMC_GPIO_SetHardwareControl(handler->gpio_port, handler->gpio_pin, handler->hwctrl);
}


__STATIC_INLINE uint32_t DIGITAL_IO_GetInput(const DIGITAL_IO_t *const handler)
{
XMC_ASSERT("DIGITAL_IO_GetInput: handler null pointer", handler != NULL);
return XMC_GPIO_GetInput(handler->gpio_port, handler->gpio_pin);
}



__STATIC_INLINE void DIGITAL_IO_SetOutputLow(const DIGITAL_IO_t *const handler)
{
XMC_ASSERT("DIGITAL_IO_SetOutputLow: handler null pointer", handler != NULL);
XMC_GPIO_SetOutputLow(handler->gpio_port, handler->gpio_pin);
}



After initializing a port pin with

DIGITAL_IO_Init(&DOUT__ENABLE)


I read the Pin with
DIGITAL_IO_GetInput(&DOUT__ENABLE)


expecting a 0, but instead getting a 1.


If I add the line above, commented with '___ADDED THIS FOR TESTING____'
or explicitly setting the pin 0 by
DIGITAL_IO_SetOutputLow(&DOUT__ENABLE);

I read a 0 as expected.


Can anyone explain this?
What am I donig wrong?
0 Likes
2 Replies
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

Sorry but I cannot reproduce your issue
#include "xmc_gpio.h"

typedef struct DIGITAL_IO
{
XMC_GPIO_PORT_t *const gpio_port; /**< port number */
const XMC_GPIO_CONFIG_t gpio_config; /**< mode, initial output level and pad driver strength / hysteresis */
const uint8_t gpio_pin; /**< pin number */
const XMC_GPIO_HWCTRL_t hwctrl; /**< Hardware port control */
} DIGITAL_IO_t;

static const DIGITAL_IO_t DOUT__ENABLE =
{
.gpio_port = XMC_GPIO_PORT2,
.gpio_pin = 14,
.gpio_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM
},
.hwctrl = XMC_GPIO_HWCTRL_DISABLED
};


#if 0
void XMC_GPIO_Init(XMC_GPIO_PORT_t *const port, const uint8_t pin, const XMC_GPIO_CONFIG_t *const config)
{
XMC_ASSERT("XMC_GPIO_Init: Invalid port", XMC_GPIO_CHECK_PORT(port));
XMC_ASSERT("XMC_GPIO_Init: Invalid mode", XMC_GPIO_IsModeValid(config->mode));

/* Switch to input */
port->IOCR[pin >> 2U] &= (uint32_t)~(PORT_IOCR_PC_Msk << (PORT_IOCR_PC_Size * (pin & 0x3U)));

/* HW port control is disabled */
port->HWSEL &= ~(uint32_t)((uint32_t)PORT_HWSEL_Msk << ((uint32_t)pin << 1U));


/* Enable digital input */
if (XMC_GPIO_CHECK_ANALOG_PORT(port))
{
port->PDISC &= ~(uint32_t)((uint32_t)0x1U << pin);
}
else
{
if ((config->mode & XMC_GPIO_MODE_OE) != 0)
{
/* If output is enabled */

/* Set output level */
port->OMR = (uint32_t)config->output_level << pin;

/* Set output driver strength */
port->PDR[pin >> 3U] &= (uint32_t)~(PORT_PDR_Msk << ((uint32_t)PORT_PDR_Size * ((uint32_t)pin & 0x7U)));
port->PDR[pin >> 3U] |= (uint32_t)config->output_strength << ((uint32_t)PORT_PDR_Size * ((uint32_t)pin & 0x7U));

port->OMR = (uint32_t)config->output_level << pin; /* <---- ___ADDED THIS FOR TESTING____ */
}
}

/* Set mode */
port->IOCR[pin >> 2U] |= (uint32_t)config->mode << ((uint32_t)PORT_IOCR_PC_Size * ((uint32_t)pin & 0x3U));
}
#endif



void DIGITAL_IO_Init(const DIGITAL_IO_t *const handler)
{
XMC_GPIO_Init(handler->gpio_port, handler->gpio_pin, &handler->gpio_config);
XMC_GPIO_SetHardwareControl(handler->gpio_port, handler->gpio_pin, handler->hwctrl);
}


__STATIC_INLINE uint32_t DIGITAL_IO_GetInput(const DIGITAL_IO_t *const handler)
{
XMC_ASSERT("DIGITAL_IO_GetInput: handler null pointer", handler != NULL);
return XMC_GPIO_GetInput(handler->gpio_port, handler->gpio_pin);
}



__STATIC_INLINE void DIGITAL_IO_SetOutputLow(const DIGITAL_IO_t *const handler)
{
XMC_ASSERT("DIGITAL_IO_SetOutputLow: handler null pointer", handler != NULL);
XMC_GPIO_SetOutputLow(handler->gpio_port, handler->gpio_pin);
}

int main(void)
{
uint32_t input;
DIGITAL_IO_Init(&DOUT__ENABLE);
input = DIGITAL_IO_GetInput(&DOUT__ENABLE);

while(1);
}



Regards,
Jesus
0 Likes
User9906
Level 2
Level 2
Thanks for your quick response!

In the meantime I figured out that the ECAT_SSC app was the reason for my strange behavior.
I was not using the latest version of this app and a bug (missing initialization, having been fixed in the meantime) was randomly compromising the output settings of the port my pin belongs to.

Thanks for your support!
0 Likes