TC37x I2C iLLD enableModule resets the MCU

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

cross mob
gotthard
Level 1
Level 1
10 sign-ins 5 questions asked 5 sign-ins

Hello all,

I am trying to enable I2C communication on TC377 with HighTec compiler but I am facing an issue with function IfxI2c_enableModule which is called by IfxI2c_I2c_initModule. During the execution of enableModule function, line:

while (i2c->CLC1.B.RMC != 1U)
{}

resets the MCU. Inside main function, I have a SYSTEM_Init function that initializes the PLL. If I2C init function is called before initializing the PLL, enableModule function will execute without resetting the MCU but I am still not able to transmit something over I2C. If I2C init is called after PLL init, it causes MCU reset. Does anyone have any idea what could cause this issue? I will provide SYSTEM_Init function code that initialises the PLL which might be helpful.

static void system_set_pll(const PllInitValue_t *pPllInitValue)
{
unsigned int k;

unlock_safety_wdtcon();

/* check whether we are running from backup clock (if not force it to this clock) */
if (0 != pSCU->CCUCON0.B.CLKSEL)
{
Ifx_SCU_CCUCON0 ccucon0 = pSCU->CCUCON0;
ccucon0.B.CLKSEL = 0; /* Select the EVR as fsource0/1/2 for the clock distribution */
ccucon0.B.UP = 1; /* Update the ccucon0 register */

while (pSCU->CCUCON0.B.LCK)
;

pSCU->CCUCON0.U = ccucon0.U;

while (pSCU->CCUCON0.B.LCK)
;
}

/* check: SYSPLL and PERPLL in powerdown mode; force it */
if (0 == pSCU->SYSPLLSTAT.B.PWDSTAT)
{
/* power down (avoid glitches during update) */
pSCU->SYSPLLCON0.B.PLLPWD = 0;
/* wait until power down mode reached */
while (0 == pSCU->SYSPLLSTAT.B.PWDSTAT)
;
}
if (0 == pSCU->PERPLLSTAT.B.PWDSTAT)
{
/* power down (avoid glitches during update) */
pSCU->PERPLLCON0.B.PLLPWD = 0;
/* wait until power down mode reached */
while (0 == pSCU->PERPLLSTAT.B.PWDSTAT)
;
}

/* setup the oscillator */
pSCU->OSCCON.U = pPllInitValue->valOSCCON;

lock_safety_wdtcon();

/* we need some delay here (Ifx sources use 5 ms) */
/* without this delay startup on TriBoard-TC3x7 is not reliable */
wait(5000);

/* wait until PLLLV and PLLHV flags are set */
while ((pSCU->OSCCON.B.PLLLV == 0) || (pSCU->OSCCON.B.PLLHV == 0))
;

unlock_safety_wdtcon();
/* setup SYSPLL (incl. power up) */
pSCU->SYSPLLCON0.U = pPllInitValue->valSYSPLLCON0; /* set P,N divider */
/* setup PERPLL (incl. power up) */
pSCU->PERPLLCON0.U = pPllInitValue->valPERPLLCON0; /* set P,N divider */
/* wait until power up is finished */
while ((1 == pSCU->SYSPLLSTAT.B.PWDSTAT) || (1 == pSCU->PERPLLSTAT.B.PWDSTAT))
;

/* wait until SYSPLL K2 operation is stable */
while (0 == pSCU->SYSPLLSTAT.B.K2RDY)
;
pSCU->SYSPLLCON1.U = pPllInitValue->valSYSPLLCON1; /* set K2 divider */
/* wait until SYSPLL K2 operation is stable */
while (0 == pSCU->SYSPLLSTAT.B.K2RDY)
;

/* wait until PERPLL K2 and K3 operation is stable */
while ((0 == pSCU->PERPLLSTAT.B.K2RDY) || (0 == pSCU->PERPLLSTAT.B.K3RDY))
;
pSCU->PERPLLCON1.U = pPllInitValue->valPERPLLCON1; /* set K2,K3 divider */
/* wait until PERPLL K2 and K3 operation is stable */
while ((0 == pSCU->PERPLLSTAT.B.K2RDY) || (0 == pSCU->PERPLLSTAT.B.K3RDY))
;

/* restart SYSPLL and PERPLL locking (with latest settings) */
pSCU->SYSPLLCON0.B.RESLD = 1;
pSCU->PERPLLCON0.B.RESLD = 1;
/* wait for SYSPLL and PERPLL locked */
while ((0 == pSCU->SYSPLLSTAT.B.LOCK) || (0 == pSCU->PERPLLSTAT.B.LOCK))
;

/* setup CCU dividers */
while (pSCU->CCUCON1.B.LCK)
;
pSCU->CCUCON1.U = pPllInitValue->valCCUCON1;

while (pSCU->CCUCON2.B.LCK)
;
pSCU->CCUCON2.U = pPllInitValue->valCCUCON2;

while (pSCU->CCUCON0.B.LCK)
;
pSCU->CCUCON0.U = pPllInitValue->valCCUCON0 | (1 << IFX_SCU_CCUCON0_UP_OFF);

lock_safety_wdtcon();

/* wait for SYSPLL locked */
while ((0 == pSCU->SYSPLLSTAT.B.LOCK))
;

/* update K dividers for stepping up to final clock */
k = pSCU->SYSPLLCON1.B.K2DIV;
/* wait some time (100 us) */
wait(100);
while (k > pPllInitValue->finalK)
{
Ifx_SCU_SYSPLLCON1 pllcon1 = pSCU->SYSPLLCON1;

--k;
/* prepare value to write */
pllcon1.B.K2DIV = k;
/* wait until K2 operation is stable */
while (0 == pSCU->SYSPLLSTAT.B.K2RDY)
;
unlock_safety_wdtcon();
pSCU->SYSPLLCON1 = pllcon1;
lock_safety_wdtcon();
/* wait some time (100 us) */
wait(100);
}
}

This function is called with the following parameter:

/* 200/100 MHz @ 20MHz ext. clock */
static const PllInitValue_t g_PllInitValue_200_100 =
{
/* OSCCON, SYSPLLCON0, SYSPLLCON1, CCUCON0, CCUCON1, CCUCON2, finalK, PERPLLCON0, PERPLLCON1 */
0x0005001C, 0x41057600, 0x00000005, 0x16220122, 0x21120012, 0x00001201, 2, 0x00053E00, 0x00000101
};

Thank you in advance

Greetings

 

0 Likes
1 Solution
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

Can you try I2C_Read_Ext_Device_1_KIT_397_TFT or adapt to something similar and check? Also, check if the hardware connection/pull-up resistor is correct.

Thanks.

View solution in original post

0 Likes
2 Replies
TBencher
Level 6
Level 6
25 solutions authored 25 likes received 5 questions asked

Hi Gotthard,

thanks for your question. Please could you tell us which board you are currently using?
Did you try to run your i2C setup separately?

Best regards,

TBencher

0 Likes
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

Can you try I2C_Read_Ext_Device_1_KIT_397_TFT or adapt to something similar and check? Also, check if the hardware connection/pull-up resistor is correct.

Thanks.

0 Likes