示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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);
}
示例#4
0
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);
}
示例#5
0
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();
}
示例#6
0
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);
}
示例#7
0
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);
}
示例#8
0
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));
}
示例#9
0
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);
}
示例#10
0
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;
}
示例#11
0
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);
}
示例#12
0
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
}
示例#13
0
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
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
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);
}