void IfxGtm_Cmu_setClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, float32 frequency) { float32 t = (IfxGtm_Cmu_getGclkFrequency(gtm) / frequency) - 1; uint32 cnt = (uint32)t; if ((t - (float32)cnt) > 0.5) { /* Round to nearest */ cnt++; } uint16 psw = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(psw); /* FIXME is this required ? */ switch (clkIndex) { case IfxGtm_Cmu_Clk_0: case IfxGtm_Cmu_Clk_1: case IfxGtm_Cmu_Clk_2: case IfxGtm_Cmu_Clk_3: case IfxGtm_Cmu_Clk_4: case IfxGtm_Cmu_Clk_5: gtm->CMU.CLK0_5[clkIndex].CTRL.B.CLK_CNT = cnt; break; case IfxGtm_Cmu_Clk_6: gtm->CMU.CLK_6.CTRL.B.CLK_CNT = cnt; break; case IfxGtm_Cmu_Clk_7: gtm->CMU.CLK_7.CTRL.B.CLK_CNT = cnt; break; default: break; } IfxScuWdt_setCpuEndinit(psw); }
void IfxPort_setPinModeLvdsHigh(Ifx_P *port, uint8 pinIndex, IfxPort_Mode mode, IfxPort_ControlledBy enablePortControlled) { uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(passwd); if (mode < IfxPort_Mode_outputPushPullGeneral) { if (pinIndex < 2) { port->LPCR0.B_P21.RDIS_CTRL = enablePortControlled; port->LPCR0.B_P21.RX_DIS = 0; } else { port->LPCR1.B_P21.RDIS_CTRL = enablePortControlled; port->LPCR1.B_P21.RX_DIS = 0; } } else { port->LPCR2.B_P21.TDIS_CTRL = enablePortControlled; port->LPCR2.B_P21.TX_DIS = 0; port->LPCR2.B_P21.TX_PD = 0; } IfxScuWdt_setCpuEndinit(passwd); }
void IfxPort_resetESR(Ifx_P *port, uint8 pinIndex) { uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(passwd); __ldmst(&port->ESR.U, 1U << pinIndex, 0); IfxScuWdt_setCpuEndinit(passwd); }
void IfxStm_resetModule(Ifx_STM *stm) { uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(passwd); stm->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */ stm->KRST1.B.RST = 1; IfxScuWdt_setCpuEndinit(passwd); while (0 == stm->KRST0.B.RSTSTAT) /* Wait until reset is executed */ {} IfxScuWdt_clearCpuEndinit(passwd); stm->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */ IfxScuWdt_setCpuEndinit(passwd); }
float32 IfxScuCcu_setSpbFrequency(float32 spbFreq) { /* TODO: check whether it is necessary to disable trap and/or the safety */ uint16 l_EndInitPW; uint16 l_SEndInitPW; Ifx_SCU_CCUCON0 ccucon0; float32 inputFreq = IfxScuCcu_getSourceFrequency(); uint32 spbDiv = (uint32)(inputFreq / spbFreq); spbDiv = __maxu(spbDiv, 2); if ((spbDiv >= 7) && (spbDiv < 14) && ((spbDiv & 1) == 1)) { spbDiv = spbDiv - 1; } if (spbDiv == 14) { spbDiv = 12; } l_EndInitPW = IfxScuWdt_getCpuWatchdogPassword(); l_SEndInitPW = IfxScuWdt_getSafetyWatchdogPassword(); IfxScuWdt_clearCpuEndinit(l_EndInitPW); SCU_TRAPDIS.U = SCU_TRAPDIS.U | 0x3E0U; IfxScuWdt_setCpuEndinit(l_EndInitPW); IfxScuWdt_clearSafetyEndinit(l_SEndInitPW); ccucon0.U = SCU_CCUCON0.U; ccucon0.B.SPBDIV = spbDiv; ccucon0.B.UP = 1; SCU_CCUCON0.U = ccucon0.U; IfxScuWdt_setSafetyEndinit(l_SEndInitPW); IfxScuWdt_clearCpuEndinit(l_EndInitPW); SCU_TRAPDIS.U = SCU_TRAPDIS.U & (uint32)~0x3E0UL; IfxScuWdt_setCpuEndinit(l_EndInitPW); while (SCU_CCUCON0.B.LCK != 0U) {} return IfxScuCcu_getSpbFrequency(); }
void IfxPort_setPinPadDriver(Ifx_P *port, uint8 pinIndex, IfxPort_PadDriver padDriver) { uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(passwd); { volatile uint32 *pdr = (volatile uint32 *)&(port->PDR0.U); uint8 pdrIndex = (pinIndex / 8); uint8 shift = (pinIndex & 0x7U) * 4; __ldmst(&(pdr[pdrIndex]), (0xFUL << shift), (padDriver << shift)); } IfxScuWdt_setCpuEndinit(passwd); }
void IfxPort_setPinModeLvdsMedium(Ifx_P *port, uint8 pinIndex, IfxPort_PadDriver lvdsPadDriver, IfxPort_PadSupply padSupply) { uint32 pdrOffset = (pinIndex / 8); uint32 shift = ((pinIndex / 2) * 8); uint32 lpcrOffset = (pinIndex / 2); volatile Ifx_P_PDR0 *pdr = &(port->PDR0); volatile Ifx_P_LPCR0 *lpcr = &(port->LPCR0); uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(passwd); { pdr[pdrOffset].U = (lvdsPadDriver << shift); /* configuring LVDS mode */ lpcr[lpcrOffset].B.PS1 = padSupply; } IfxScuWdt_setCpuEndinit(passwd); }
void IfxPort_setPinMode(Ifx_P *port, uint8 pinIndex, IfxPort_Mode mode) { volatile Ifx_P_IOCR0 *iocr = &(port->IOCR0); uint8 iocrIndex = (pinIndex / 4); uint8 shift = (pinIndex & 0x3U) * 8; uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); if ((port == &MODULE_P40) || (port == &MODULE_P41)) { IfxScuWdt_clearCpuEndinit(passwd); port->PDISC.U &= ~(1 << pinIndex); IfxScuWdt_setCpuEndinit(passwd); } __ldmst(&iocr[iocrIndex].U, (0xFFUL << shift), (mode << shift)); }
void IfxGtm_Cmu_setEclkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex, float32 frequency) { float32 f; float32 bestDistance = frequency; float32 fIn = IfxGtm_Cmu_getGclkFrequency(gtm) * 2; uint32 z, n, nBest = 1, zBest = 1; float32 t; for (z = 1; z < 0xFFFFFF; z++) { boolean endLoop = FALSE; t = fIn / z; for (n = z; n > 0; n--) { float32 distance; f = t * n; distance = fabsf(frequency - f); if (distance < bestDistance) { bestDistance = distance; nBest = n; zBest = z; } if (bestDistance < 0.1) { endLoop = TRUE; break; } } if (endLoop) { break; } } uint16 psw = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(psw); /* FIXME is this required ? */ gtm->CMU.ECLK[clkIndex].NUM.B.ECLK_NUM = zBest; gtm->CMU.ECLK[clkIndex].NUM.B.ECLK_NUM = zBest; /* write twice to be sure */ gtm->CMU.ECLK[clkIndex].DEN.B.ECLK_DEN = nBest; IfxScuWdt_setCpuEndinit(psw); }
static boolean IfxScuCcu_isOscillatorStable(void) { uint16 endinitPw = IfxScuWdt_getCpuWatchdogPassword(); sint32 TimeoutCtr = IFXSCUCCU_OSC_STABLECHK_TIME; boolean status = 0; /* Mode External Crystal / Ceramic Resonator Mode and External Input Clock. * The oscillator Power-Saving Mode is not entered */ SCU_OSCCON.B.MODE = 0U; if (IFX_CFG_SCU_XTAL_FREQUENCY <= 8000000) { SCU_OSCCON.B.OSCVAL = 2; } else { SCU_OSCCON.B.OSCVAL = 7; } /* The Oscillator Watchdog of the PLL is cleared and restarted */ SCU_OSCCON.B.OSCRES = 1U; /* wait until PLLLV and PLLHV flags are set */ while ((SCU_OSCCON.B.PLLLV == 0) || (SCU_OSCCON.B.PLLHV == 0)) { TimeoutCtr--; if (TimeoutCtr == 0) { status = 1; break; } } { /* clear and then set SMU trap (oscillator watchdog and unlock detection) */ IfxScuWdt_clearCpuEndinit(endinitPw); SCU_TRAPCLR.B.SMUT = 1U; /* TODO Can this be removed? */ SCU_TRAPDIS.B.SMUT = 1U; /* TODO Can this be removed? */ IfxScuWdt_setCpuEndinit(endinitPw); } return status; }
void IfxPort_setGroupPadDriver(Ifx_P *port, uint8 pinIndex, uint16 mask, IfxPort_PadDriver padDriver) { uint16 passwd = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(passwd); { uint32 i; uint32 pdrVal[2]; uint32 pdrMask[2]; /* initialise */ for (i = 0; i < 2; i++) { pdrVal[i] = 0; pdrMask[i] = 0; } /* calculate PDRx values and masks */ uint32 imask = (uint32)mask << pinIndex; for (i = pinIndex; i < 16; i++) { if ((imask & (1U << i)) != 0) { uint32 index = i / 8; uint32 shift = (i & 0x7U) * 4; pdrMask[index] |= (0xFUL << shift); pdrVal[index] |= (padDriver << shift); } } /* write PDRx */ for (i = 0; i < 2; i++) { if (pdrMask[i] != 0) { __ldmst(&((&(port->PDR0.U))[i]), pdrMask[i], pdrVal[i]); } } } IfxScuWdt_setCpuEndinit(passwd); }
boolean IfxCpu_setCoreMode(Ifx_CPU *cpu, IfxCpu_CoreMode mode) { // this switch is only temporary required // once the IfxCan driver is generated via lldgen, we will vary the code without #ifdef #ifdef IFX_TC27x /* FIXME Copied from old TC27xA code, check that this is up to date code */ IfxCpu_CoreMode cpuMode; boolean RetVal; IfxScu_PMCSR_REQSLP modeSet; RetVal = TRUE; modeSet = IfxScu_PMCSR_REQSLP_Idle; /* Check the mode the CPU is in */ cpuMode = IfxCpu_getCoreMode(cpu); /* if requested mode is same as current mode nothing to do */ if (cpuMode != mode) { /* transition from halt to Run */ if (IfxCpu_CoreMode_halt == cpuMode) { if (IfxCpu_CoreMode_run == mode) { Ifx_CPU_DBGSR dbgsr; if (IfxCpu_getCoreId() != IfxCpu_getIndex(cpu)) { cpu->DBGSR.B.HALT = 0x2; } else { dbgsr.U = __mfcr(CPU_DBGSR); dbgsr.B.HALT = 0x2; __mtcr(CPU_DBGSR, dbgsr.U); } } else /* cannot go to any other mode e.g. IfxCpu_CoreMode_idle */ { RetVal = FALSE; } } /* From Run to Idle or vice versa */ else { if (IfxCpu_CoreMode_run == cpuMode) { if (IfxCpu_CoreMode_idle == mode) { modeSet = IfxScu_PMCSR_REQSLP_Idle; } else { RetVal = FALSE; } } /* idle to Run */ else if (IfxCpu_CoreMode_idle == cpuMode) { if (IfxCpu_CoreMode_run == mode) { modeSet = IfxScu_PMCSR_REQSLP_Run; } else { RetVal = FALSE; } } else { RetVal = FALSE; } if (TRUE == RetVal) { /* To take care of the Work Around in A step * In A Step the PMCSR is Cpu Endinit protected * in B step it is by safety endinit*/ uint16 password; uint32 wdtCon0_Val; Ifx_SCU_WDTCPU *watchdog; watchdog = &MODULE_SCU.WDTCPU[IfxCpu_getCoreId()]; /* FIXME access to the watchdog of an other CPU, this might not work! */ password = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(password); /* password access */ watchdog->CON0.U = (password << 2U) | 0x1U; /* modify access, E=0 */ watchdog->CON0.U = (password << 2U) | 0x2U; /* password access in advance */ watchdog->CON0.U = (password << 2U) | 0x1U; /* prepare write value */ wdtCon0_Val = ((0x0000U) << 16U) | (password << 2U) | (0x3U); MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = modeSet; /* modify access, E=1, reload WDT */ watchdog->CON0.U = wdtCon0_Val; IfxScuWdt_setCpuEndinit(password); } } } return RetVal; #else uint8 reqslp; boolean retValue; IfxCpu_ResourceCpu index = IfxCpu_getIndex(cpu); /*Modes such as HALT, SLEEP and STBY are not handled at CPU level */ retValue = ((mode == IfxCpu_CoreMode_halt) || (mode == IfxCpu_CoreMode_sleep) || (mode == IfxCpu_CoreMode_stby)) ? FALSE : TRUE; reqslp = (mode == IfxCpu_CoreMode_idle) ? IfxScu_PMCSR_REQSLP_Idle : IfxScu_PMCSR_REQSLP_Run; if (retValue == TRUE) { /*Check if the same core is requesting to change the core run mode */ if (IfxCpu_getCoreId() != index) { /*Request is for the other core */ /*To access PMCSR of other CPUs handle the safety EndInit protection */ uint16 safetyWdtPw = IfxScuWdt_getSafetyWatchdogPassword(); IfxScuWdt_clearSafetyEndinit(safetyWdtPw); MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = reqslp; IfxScuWdt_setSafetyEndinit(safetyWdtPw); cpu->DBGSR.B.HALT = 2; /*reset the HALT bit, if it is already done it is no harm in writing again */ } else { /*Request is for self, this request normally only for halt, otherwise the core is already running anyway! */ /*To access PMCSR of self handle the cpu EndInit protection */ uint16 cpuWdtPw = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(cpuWdtPw); MODULE_SCU.PMCSR[(uint32)index].B.REQSLP = reqslp; IfxScuWdt_setCpuEndinit(cpuWdtPw); } } return retValue; #endif }
void Appli_DsadcInit(void) { #ifdef iLLD Appli_DsadcModule_Init(); #else uint16 endinitPw; endinitPw = IfxScuWdt_getCpuWatchdogPassword (); IfxScuWdt_clearCpuEndinit(endinitPw); DSADC_CLC.B.DISR = 0;; // enable module clock while (DSADC_CLC.B.DISS == 1); // wait until module is enabled DSADC_KRST0.B.RST = 1; DSADC_KRST1.B.RST = 1; while (DSADC_KRST0.B.RSTSTAT == 0); IfxScuWdt_setCpuEndinit(endinitPw); DSADC_GLOBCFG.B.MCSEL = 1; //select fDSD /* first we set the inputs to GND to measure offset error */ DSADC_MODCFG0.U = 0x8682800B; //DSADC_MODCFG0.U = 0xA682800B; //MODCFG0.APC = 0 = alwasy runnign //MODCFG0.GCEN = 0 = normal operation //MODCFG0.MCFG = 01B = high-performance+anti-alias filter //MODCFG0.CMVS = 10B = VCM is VAREF/2 = 2.5V //MODCFG0.DIVM = 2 = fMOD = fCLK/6 = 100MHz/6 //MODCFG0.INSEL = 0 = input pin position A //MODCFG0.GAINSEL = 0 = gain factor 1 //MODCFG0.INCFGN = 10B = VCM //MODCFG0.INCFGP = 11B = reference GND /* set Main Comb Filter (DSADC_FCFGCx) */ DSADC_FCFGC0.U = 0x00313631; //DSADC_FCFGC0.U = 0x001F3631; //DSADC_FCFGC0.U = 0x001F3631; //FCFGC0.CFMSV = 0x31 = decimation counter start = 49 //FCFGC0.SRGM = 0 = no interrupt //FCFGC0.MFSC = 11B = Shift by 3 //FCFGC0.CFEN = 1 = CIC enabled //FCFGC0.CFMC = 10B = CIC3 selected //FCFGC0.CFMDF = 0x31 = decimation rate = 50 /* set demodulator input (DSADC_DICFGx) */ DSADC_DICFG0.U = 0x80108080; //DICFG0.DSRC = 0000B = Input Data Source = On-chip modulator (3rd order) //DICFG0.STROBE = 1 = sample trigger at rising clock edge /* set Filter Configuration Register (DSADC_FCFGMx) */ DSADC_FCFGM0.U = 0x2B; //DSADC_FCFGM0.U = 0xA; //FCFGM0.FSH = 1 = FIR0 shift to left 1 time //FCFGM0.DSH = 1 = FIR1 shift to left 1 time //FCFGM0.FIR0EN = 1 = FIR0 enabled //FCFGM0.FIR1EN = 1 = FIR1 enabled /* set Integrator (DSADC_IWCTRx) */ DSADC_IWCTR0.U = 0x0; #endif }
boolean IfxScuCcu_initErayPll(const IfxScuCcu_ErayPllConfig *cfg) { uint8 smuTrapEnable; uint16 endinit_pw, endinitSfty_pw; boolean status = 0; endinit_pw = IfxScuWdt_getCpuWatchdogPassword(); endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword(); { /* Disable TRAP for SMU (oscillator watchdog and unlock detection) */ IfxScuWdt_clearCpuEndinit(endinit_pw); smuTrapEnable = SCU_TRAPDIS.B.SMUT; SCU_TRAPDIS.B.SMUT = 1U; IfxScuWdt_setCpuEndinit(endinit_pw); } IfxScuWdt_clearSafetyEndinit(endinitSfty_pw); // ensure that PLL enabled if (!SCU_PLLERAYCON0.B.PLLPWD || SCU_PLLERAYCON0.B.VCOPWD || SCU_PLLERAYSTAT.B.PWDSTAT) { // PLLPWD=0 or VCOPWD=1 or PWDSTAT=1? // enable PLL and leave power saving mode SCU_PLLERAYCON0.B.PLLPWD = 1; SCU_PLLERAYCON0.B.VCOPWD = 0; while (SCU_PLLERAYSTAT.B.PWDSTAT) // poll PWDSTAT {} /*Wait for waitCounter corresponding to the pll step */ IfxScuCcu_wait(cfg->pllInitialStep.waitTime); } /* Enter Prescalar mode */ /* Update K and N dividers */ if (!SCU_PLLERAYSTAT.B.VCOBYST) // checking PLLERAYBYPST flag { // select "secure" K1 value - please check @silicon if K1=4 is ok while (!SCU_PLLERAYSTAT.B.K1RDY) // poll K1RDY before changing K {} SCU_PLLERAYCON1.B.K1DIV = 3; // activate VCO bypass (bit 0: VCOBYP=1) SCU_PLLERAYCON0.B.VCOBYP = 1; } while (!SCU_PLLERAYSTAT.B.K2RDY) // poll K1RDY before changing K {} SCU_PLLERAYCON1.B.K2DIV = cfg->pllInitialStep.k2Initial; SCU_PLLERAYCON0.B.PDIV = cfg->pllInitialStep.pDivider; SCU_PLLERAYCON0.B.NDIV = cfg->pllInitialStep.nDivider; /* * RESLD = 1 ==> Restart VCO lock detection * CLRFINDIS = 1 ==> Connect OSC to PLL * PLLPWD = 1 ==> PLL Power Saving Mode : Normal behaviour * NDIV = NDIV */ SCU_PLLERAYCON0.B.RESLD = 1U; SCU_PLLERAYCON0.B.CLRFINDIS = 1U; IfxScuWdt_setSafetyEndinit(endinitSfty_pw); // Wait until VCO LOCK bit is set uint32 time_out_ctr = 50000; // higher time out value as for clib_pll, since system is clocked much faster while polling the lock flag while (--time_out_ctr && !SCU_PLLERAYSTAT.B.VCOLOCK) {} // check for timeout, exit immediately (don't disable VCO bypass) of not locked if (!time_out_ctr) { status = FALSE; } IfxScuWdt_clearSafetyEndinit(endinitSfty_pw); /*Bypass VCO*/ SCU_PLLERAYCON0.B.VCOBYP = 0U; // wait until bypass has been deactivated while (SCU_PLLERAYSTAT.B.VCOBYST) // poll VCOBYST {} if (!SCU_PLLERAYSTAT.B.VCOLOCK) { status = FALSE; } IfxScuWdt_setSafetyEndinit(endinitSfty_pw); { /* Enable VCO unlock Trap if it was disabled before */ IfxScuWdt_clearCpuEndinit(endinit_pw); SCU_TRAPCLR.B.SMUT = 1U; SCU_TRAPDIS.B.SMUT = smuTrapEnable; IfxScuWdt_setCpuEndinit(endinit_pw); } return status; }
boolean IfxScuCcu_init(const IfxScuCcu_Config *cfg) { uint8 smuTrapEnable; uint16 endinit_pw, endinitSfty_pw; boolean status = 0; endinit_pw = IfxScuWdt_getCpuWatchdogPassword(); endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword(); { /* Disable TRAP for SMU (oscillator watchdog and unlock detection) */ IfxScuWdt_clearCpuEndinit(endinit_pw); smuTrapEnable = SCU_TRAPDIS.B.SMUT; SCU_TRAPDIS.B.SMUT = 1U; IfxScuWdt_setCpuEndinit(endinit_pw); } { /* Select fback (fosc-evr) as CCU input clock */ IfxScuWdt_clearSafetyEndinit(endinitSfty_pw); while (SCU_CCUCON0.B.LCK != 0U) { /*Wait till ccucon0 lock is set */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } SCU_CCUCON0.B.CLKSEL = 0; /*Select the EVR as fOSC for the clock distribution */ SCU_CCUCON0.B.UP = 1; /*Update the ccucon0 register */ /* Disconnet PLL (SETFINDIS=1): oscillator clock is disconnected from PLL */ SCU_PLLCON0.B.SETFINDIS = 1; /* Now PLL is in free running mode */ /* Select Clock Source as PLL input clock */ while (SCU_CCUCON0.B.LCK != 0U) { /*Wait till ccucon0 lock is set */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } SCU_CCUCON1.B.INSEL = 1; /*Select oscillator OSC0 as clock to PLL */ SCU_CCUCON1.B.UP = 1; /*Update the ccucon0 register */ status |= IfxScuCcu_isOscillatorStable(); IfxScuWdt_setSafetyEndinit(endinitSfty_pw); } if (status == 0) { /*Start the PLL configuration sequence */ uint8 pllStepsCount; /*Setting up P N and K2 values equate pll to evr osc freq */ { { /*Set the K2 divider value for the step corresponding to step count */ IfxScuWdt_clearSafetyEndinit(endinitSfty_pw); while (SCU_PLLSTAT.B.K2RDY == 0U) { /*Wait until K2 divider is ready */ /*No "timeout" required because Safety Endinit will give a trap */ } SCU_PLLCON1.B.K2DIV = cfg->sysPll.pllInitialStep.k2Initial; { /*change P and N divider values */ SCU_PLLCON0.B.PDIV = cfg->sysPll.pllInitialStep.pDivider; SCU_PLLCON0.B.NDIV = cfg->sysPll.pllInitialStep.nDivider; /* Disable oscillator disconnect feature * in case of PLL unlock, PLL stays connected to fref */ SCU_PLLCON0.B.OSCDISCDIS = 1; /* Connect PLL to fREF as oscillator clock is connected to PLL */ SCU_PLLCON0.B.CLRFINDIS = 1; /* Restart PLL lock detection (RESLD = 1) */ SCU_PLLCON0.B.RESLD = 1; IfxScuCcu_wait(0.000050F); /*Wait for 50us */ while (SCU_PLLSTAT.B.VCOLOCK == 0U) { /* Wait for PLL lock */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } SCU_PLLCON0.B.VCOBYP = 0; /*VCO bypass disabled */ while (SCU_CCUCON0.B.LCK != 0U) { /*Wait till ccucon registers can be written with new value */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } SCU_CCUCON0.B.CLKSEL = 0x01; /*Configure the clock distribution */ while (SCU_CCUCON0.B.LCK != 0U) { /*Wait till ccucon registers can be written with new value */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } /*Wait until the initial clock configurations take in to effect for the PLL*/ IfxScuCcu_wait(cfg->sysPll.pllInitialStep.waitTime); /*Wait for configured initial time */ { /*Write CCUCON0 configuration */ Ifx_SCU_CCUCON0 ccucon0; ccucon0.U = SCU_CCUCON0.U & ~cfg->clockDistribution.ccucon0.mask; /*update with configured value */ ccucon0.U |= (cfg->clockDistribution.ccucon0.mask & cfg->clockDistribution.ccucon0.value); ccucon0.B.CLKSEL = 0x01; /* Select fpll as CCU input clock, even if this was not selected by configuration */ ccucon0.B.UP = 1; SCU_CCUCON0 = ccucon0; /*Set update bit explicitly to make above configurations effective */ } while (SCU_CCUCON1.B.LCK != 0U) { /*Wait till ccucon registers can be written with new value */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } { /*Write CCUCON1 configuration */ Ifx_SCU_CCUCON1 ccucon1; ccucon1.U = SCU_CCUCON1.U & ~cfg->clockDistribution.ccucon1.mask; /*update with configured value */ ccucon1.U |= (cfg->clockDistribution.ccucon1.mask & cfg->clockDistribution.ccucon1.value); ccucon1.B.INSEL = 1; ccucon1.B.UP = 1; SCU_CCUCON1 = ccucon1; } while (SCU_CCUCON2.B.LCK != 0U) { /*Wait till ccucon registers can be written with new value */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } { /*Write CCUCON2 configuration */ Ifx_SCU_CCUCON2 ccucon2; ccucon2.U = SCU_CCUCON2.U & ~cfg->clockDistribution.ccucon2.mask; /*update with configured value */ ccucon2.U |= (cfg->clockDistribution.ccucon2.mask & cfg->clockDistribution.ccucon2.value); ccucon2.B.UP = 1; SCU_CCUCON2 = ccucon2; } while (SCU_CCUCON5.B.LCK != 0U) { /*Wait till ccucon registers can be written with new value */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } { /*Write CCUCON5 configuration */ Ifx_SCU_CCUCON5 ccucon5; ccucon5.U = SCU_CCUCON5.U & ~cfg->clockDistribution.ccucon5.mask; /*update with configured value */ ccucon5.U |= (cfg->clockDistribution.ccucon5.mask & cfg->clockDistribution.ccucon5.value); ccucon5.B.UP = 1; SCU_CCUCON5 = ccucon5; } { /*Write CCUCON6 configuration */ Ifx_SCU_CCUCON6 ccucon6; ccucon6.U = SCU_CCUCON6.U & ~cfg->clockDistribution.ccucon6.mask; /*update with configured value */ ccucon6.U |= (cfg->clockDistribution.ccucon6.mask & cfg->clockDistribution.ccucon6.value); SCU_CCUCON6 = ccucon6; } { /*Write CCUCON7 configuration */ Ifx_SCU_CCUCON7 ccucon7; ccucon7.U = SCU_CCUCON7.U & ~cfg->clockDistribution.ccucon7.mask; /*update with configured value */ ccucon7.U |= (cfg->clockDistribution.ccucon7.mask & cfg->clockDistribution.ccucon7.value); SCU_CCUCON7 = ccucon7; } { /*Write CCUCON8 configuration */ Ifx_SCU_CCUCON8 ccucon8; ccucon8.U = SCU_CCUCON8.U & ~cfg->clockDistribution.ccucon8.mask; /*update with configured value */ ccucon8.U |= (cfg->clockDistribution.ccucon8.mask & cfg->clockDistribution.ccucon8.value); SCU_CCUCON8 = ccucon8; } } IfxScuWdt_setSafetyEndinit(endinitSfty_pw); } } { /*Write Flash waitstate configuration */ Ifx_FLASH_FCON fcon; fcon.U = FLASH0_FCON.U & ~cfg->flashFconWaitStateConfig.mask; /*update with configured value */ fcon.U &= ~cfg->flashFconWaitStateConfig.mask; fcon.U |= (cfg->flashFconWaitStateConfig.mask & cfg->flashFconWaitStateConfig.value); { IfxScuWdt_clearCpuEndinit(endinit_pw); FLASH0_FCON = fcon; IfxScuWdt_setCpuEndinit(endinit_pw); } } /*Start Pll ramp up sequence */ for (pllStepsCount = 0; pllStepsCount < cfg->sysPll.numOfPllDividerSteps; pllStepsCount++) { /*iterate through number of pll steps */ { IfxScuWdt_clearSafetyEndinit(endinitSfty_pw); /*Configure K2 divider */ while (SCU_PLLSTAT.B.K2RDY == 0U) { /*Wait until K2 divider is ready */ /*No "timeout" required, because if it hangs, Safety Endinit will give a trap */ } /*Now set the K2 divider value for the step corresponding to step count */ SCU_PLLCON1.B.K2DIV = cfg->sysPll.pllDividerStep[pllStepsCount].k2Step; IfxScuWdt_setSafetyEndinit(endinitSfty_pw); } /*call the hook function if configured */ if (cfg->sysPll.pllDividerStep[pllStepsCount].hookFunction != (IfxScuCcu_PllStepsFunctionHook)0) { cfg->sysPll.pllDividerStep[pllStepsCount].hookFunction(); } /*Wait for waitCounter corresponding to the pll step */ IfxScuCcu_wait(cfg->sysPll.pllDividerStep[pllStepsCount].waitTime); } } { /* Enable oscillator disconnect feature */ IfxScuWdt_clearSafetyEndinit(endinitSfty_pw); SCU_PLLCON0.B.OSCDISCDIS = 0U; IfxScuWdt_setSafetyEndinit(endinitSfty_pw); } { /* Enable VCO unlock Trap if it was disabled before */ IfxScuWdt_clearCpuEndinit(endinit_pw); SCU_TRAPCLR.B.SMUT = 1U; SCU_TRAPDIS.B.SMUT = smuTrapEnable; IfxScuWdt_setCpuEndinit(endinit_pw); } return status; }
void IfxGtm_Cmu_setGclkFrequency(Ifx_GTM *gtm, float32 frequency) { float32 f; float32 bestDistance = frequency; float32 fIn = IfxGtm_Cmu_getModuleFrequency(gtm); uint32 z, n, nBest = 1, zBest = 1; float32 t; #if 1 for (z = 1; z < 0xFFFFFF; z++) { boolean endLoop = FALSE; t = fIn / z; for (n = z; n > 0; n--) { float32 distance; f = t * n; distance = fabsf(frequency - f); if (distance < bestDistance) { bestDistance = distance; nBest = n; zBest = z; } if (bestDistance < 0.1) { endLoop = TRUE; break; } } if (endLoop) { break; } } #else for (n = 1; n < 0xFFFFFF; n++) { float32 distance; /* get best z */ z = floorf(frequency * n / fIn); t = fIn / n; /* lower value */ f = t * z; distance = fabsf(frequency - f); if (distance < bestDistance) { bestDistance = distance; nBest = n; zBest = z; } /* upper value */ f = t * (z + 1); distance = fabsf(frequency - f); if (distance < bestDistance) { bestDistance = distance; nBest = n; zBest = z; } if (bestDistance == 0.0) { break; } } #endif uint16 psw = IfxScuWdt_getCpuWatchdogPassword(); IfxScuWdt_clearCpuEndinit(psw); /* FIXME is this required ? */ gtm->CMU.GCLK_NUM.B.GCLK_NUM = zBest; gtm->CMU.GCLK_NUM.B.GCLK_NUM = zBest; /* write twice to be sure */ gtm->CMU.GCLK_DEN.B.GCLK_DEN = nBest; IfxScuWdt_setCpuEndinit(psw); }