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

cross mob
Not applicable
Hello,

I am looking at the errata to find out how to reset the I2C system and have some questions about the following text from the H004 entry

4. Clear all status bits and reinitialize the IIC USIC channel if necessary.
5. Reprogram the Pn_IOCRx.PCy bit fields to select the SCL and SDA port
functions.

For 4, what steps would be involved in this IIC USIC channel reinitialization? This text is too vague to be usable.
For 5, what should be set for this?

I was provided the following code as another way to reset the I2C Slave, but cannot find where the macros and variables are defined so this is looking like little more than pseudo code.

/* Disable SDA and SCL output pin functions */
XMC_GPIO_SetMode(SCL_PIN, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetMode(SDA_PIN, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
/* Flush the contents of the FIFO */
XMC_USIC_CH_TXFIFO_Flush(I2C_CH_NUM);
XMC_USIC_CH_RXFIFO_Flush(I2C_CH_NUM);
/* Invalidate the internal transmit buffer */
XMC_USIC_CH_SetTransmitBufferStatus(I2C_CH_NUM, XMC_USIC_CH_TBUF_STATUS_SET_IDLE);
/* Re-enable the SDA and SCL output pin functions following the recovery sequence */
XMC_GPIO_SetMode(SCL_PIN, XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2);
XMC_GPIO_SetMode(SDA_PIN, XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2);

I think that
XMC_GPIO_MODE_OUTPUT_PUSH_PULL is ~0x1F
XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT2 is 0x18

but I have no idea what XMC_USIC_CH_TBUF_STATUS_SET_IDLE although I think it is for a bit in the FMR register.

Help and some example code would be appreciated.

Thanks,

Joe
0 Likes
3 Replies
User8683
Level 4
Level 4
First like received
You are not likely to get good detailed answers from the Infineon support staff in these forums. The forums seem to be understaffed and have people who don't actually get much time to play with the hardware. I faced continued frustration when I looked for and asked about this kind of information. My local chip supplier also commented that Infineon is an odd company. Anyway, here is how I reset the slave I2C on the XMC1100 in the event of protocol errors:

The following code is using pins 2 and 3 on the XMC1100


#define I2CSLAVE_OPENDRAIN_OUT 0x18U
#define PORT_BASE_OFFSET 0
#define SDA_PORT_PIN 2
#define SCL_PORT_PIN 3

typedef struct I2CSLAVE_PinConfigurationType
{
PORTS_TypeDef* SCL_PortBase; /* SCL Port address */
uint8_t SCL_Pin; /* SCL Pin Number */
PORTS_TypeDef* SDA_PortBase; /* SDA Port address */
uint8_t SDA_Pin; /* SDA Pin Number */
} I2CSLAVE_PinConfigurationType;

I2CSLAVE_PinConfigurationType pinConfiguration;

/*******************************************************************************
* @brief Used to reset communications in the event of a communications failure.
*
* Re-entrancy: NO
******************************************************************************/
void I2CSLAVE_resetCommunications()
{
uint32_t offset;

/* Disable the I2C to release SDA,SCL */

/* Configure SCL port pin as General-purpose input without pull-up */
offset = SCL_PORT_PIN - PORT_BASE_OFFSET;
pinConfiguration.SCL_PortBase->IOCR0 &= ~((uint32_t)0x1F << (3U + (offset << 3)));

/* Configure SDA port pin as General-purpose input without pull-up */
offset = SDA_PORT_PIN - PORT_BASE_OFFSET;
pinConfiguration.SDA_PortBase->IOCR0 &= ~((uint32_t)0x1F << (3U + (offset << 3)));

/* Flush the buffers */
SET_BIT( pI2CRegisters->TRBSCR, USIC_CH_TRBSCR_FLUSHTB_Pos );
SET_BIT( pI2CRegisters->TRBSCR, USIC_CH_TRBSCR_FLUSHRB_Pos );

/* Invalidate the transmit buffer state */
WR_REG( pI2CRegisters->FMR, USIC_CH_FMR_MTDV_Msk, USIC_CH_FMR_MTDV_Pos, 0x02 );

// Clear error bits
pI2CRegisters->PSCR |= 0x3FF;

/* Set SCL and SDA high */
pinConfiguration.SCL_PortBase->OMR |= (uint32_t)SHIFT_ONE << SCL_PORT_PIN;
pinConfiguration.SDA_PortBase->OMR |= (uint32_t)SHIFT_ONE << SDA_PORT_PIN;

/* Reenable the I2C to release SDA,SCL */

/* Configure SCL port pin as Open-drain General-purpose output */
offset = SCL_PORT_PIN - PORT_BASE_OFFSET;
pinConfiguration.SCL_PortBase->IOCR0 |= ((uint32_t)I2CSLAVE_OPENDRAIN_OUT << (3U + (offset << 3)));

/* Configure SDA port pin as Open-drain General-purpose output */
offset = SDA_PORT_PIN - PORT_BASE_OFFSET;
pinConfiguration.SDA_PortBase->IOCR0 |= ((uint32_t)I2CSLAVE_OPENDRAIN_OUT << (3U + (offset << 3)));

/* Physical port to pin mapping */
/* PORT Macro definitions for IOCR_OE, IOCR_PCR & HWSEL_HW */
WR_REG(PORT1->IOCR0, 0x00b80000U, PORT_IOCR_PC2_PCR_Pos, 0x17U); /*P1.2 : PORT1_IOCR0_PC2_PCR and PORT1_IOCR0_PC2_OE */
WR_REG(PORT1->IOCR0, 0xb8000000U, PORT_IOCR_PC3_PCR_Pos, 0x16U); /*P1.3 : PORT1_IOCR0_PC3_PCR and PORT1_IOCR0_PC3_OE */
}


Let me know if you have questions,

Jason
0 Likes
chismo
Employee
Employee
First like received
Hello Joe,

I am the one who provided the code snippets. Sorry I didn't mention they are using the XMC_Lib and based on DAVE4.
The suffix determines which specific Lib is being used.
"XMC_GPIO_..." refers to the one for GPIO while "XMC_USIC_..." refers to the one for USIC.

Therefore, the code has to include the header files:

#include
#include


If you are using DAVE3 however, then the above will not work. You can reference Jason's code.

Regards,
Min Wei
0 Likes
chismo
Employee
Employee
First like received
Hello Jason,

Sorry that we were not able to meet your expectations previously. Hopefully we can do better the next time.
In any case, it really helps that experienced users like you are willing to contribute to the forums.
Thanks!

Regards,
Min Wei
0 Likes