Esempio n. 1
0
boolean IfxStm_initCompare(Ifx_STM *stm, IfxStm_CompareConfig *config)
{
    sint32        index;
    boolean       result;
    Ifx_STM_CMCON comcon = stm->CMCON;
    Ifx_STM_ICR   icr    = stm->ICR;

    index = IfxStm_getIndex(stm);

    if ((config->triggerInterruptEnabled > 0) && (index >= 0))
    {                           /* configure interrupt */
        volatile Ifx_SRC_SRCR *srcr;

        if (config->comparatorInterrupt == IfxStm_ComparatorInterrupt_ir0)
        {
            srcr = &(MODULE_SRC.STM.STM[index].SR0);
        }
        else
        {
            srcr = &(MODULE_SRC.STM.STM[index].SR1);
        }

        IfxSrc_init(srcr, config->servProvider, config->triggerInterruptEnabled);
        IfxSrc_enable(srcr);
    }

    /*Configure the comparator ticks */
    stm->CMP[config->comparator].U = IfxStm_getOffsetTimer(stm, (uint8)config->compareOffset) + config->ticks;

    if (config->comparator == 0)
    {
        comcon.B.MSIZE0  = config->compareSize;
        comcon.B.MSTART0 = config->compareOffset;
        icr.B.CMP0OS     = config->comparatorInterrupt;
        icr.B.CMP0EN     = config->triggerInterruptEnabled ? 1 : 0;
        result           = TRUE;
    }
    else if (config->comparator == 1)
    {
        comcon.B.MSIZE1  = config->compareSize;
        comcon.B.MSTART1 = config->compareOffset;
        icr.B.CMP1OS     = config->comparatorInterrupt;
        icr.B.CMP1EN     = config->triggerInterruptEnabled ? 1 : 0;
        result           = TRUE;
    }
    else
    {
        /*Invalid value */
        result = FALSE;
    }

    stm->ICR   = icr;
    stm->CMCON = comcon;

    return result;
}
boolean IfxGtm_Tom_Timer_init(IfxGtm_Tom_Timer *driver, IfxGtm_Tom_Timer_Config *config)
{
    boolean                result = TRUE;
    IfxGtm_Tom_Timer_Base *base   = &driver->base;
    uint16                 maskShift;

    IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->base.countDir == IfxStdIf_Timer_CountDir_up);    /* only this mode is supported */

    driver->gtm          = config->gtm;
    driver->tomIndex     = config->tom;
    driver->tom          = &config->gtm->TOM[config->tom];
    driver->timerChannel = config->timerChannel;
    base->triggerEnabled = config->base.trigger.enabled;

    if (base->triggerEnabled)
    {
        driver->triggerChannel = config->triggerOut->channel;
    }
    else
    {
        driver->triggerChannel = driver->timerChannel; // Set to timer channel to disable its use
    }

    if (config->timerChannel <= 7)
    {
        driver->tgc[0] = IfxGtm_Tom_Ch_getTgcPointer(driver->tom, 0);
        driver->tgc[1] = IfxGtm_Tom_Ch_getTgcPointer(driver->tom, 1);
    }
    else
    {
        driver->tgc[0] = IfxGtm_Tom_Ch_getTgcPointer(driver->tom, 1);
        driver->tgc[1] = NULL_PTR; /* NOTE currently no concatenation between TOMs */
    }

    driver->channelsMask[1]                  = 0;
    driver->tgcGlobalControlApplyUpdate[1]   = 0;
    driver->tgcGlobalControlDisableUpdate[1] = 0;

    /* Initialize the timer part */
    /* FIXME add IfxGtm_Tom_Ch_configurePwmMode() and use it */
    IfxGtm_Tom_Ch_setClockSource(driver->tom, driver->timerChannel, config->clock);
    IfxGtm_Tom_Ch_setTriggerOutput(driver->tom, driver->timerChannel, IfxGtm_Tom_Ch_OutputTrigger_generate);

    IfxGtm_Tom_Timer_updateInputFrequency(driver);

    if ((config->base.minResolution > 0) && ((1.0 / base->clockFreq) > config->base.minResolution))
    {
        result = FALSE;
        IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, FALSE);
    }
    else
    {}

    IfxGtm_Tom_Timer_setFrequency(driver, config->base.frequency);
    driver->offset = IfxStdIf_Timer_sToTick(driver->base.clockFreq, 1.0 / config->base.frequency * config->base.startOffset);

    IfxGtm_Tom_Ch_setCounterValue(driver->tom, driver->timerChannel, driver->offset);

    /* Initialize the trigger part */
    maskShift = (config->timerChannel <= 7) ? 0 : 8;
    IfxGtm_Tom_Timer_addToChannelMask(driver, driver->timerChannel);

    if (base->triggerEnabled)
    {
        IfxGtm_Tom_Ch triggerChannel     = driver->triggerChannel;
        uint16        triggerChannelMask = 1 << (triggerChannel - maskShift);
        /* TO DO: enable the trigger to be not in the same TGC group as the timer */

        IfxGtm_Tom_Ch_setSignalLevel(driver->tom, triggerChannel, config->base.trigger.risingEdgeAtPeriod ? Ifx_ActiveState_high : Ifx_ActiveState_low);
        IfxGtm_Tom_Ch_setCounterValue(driver->tom, triggerChannel, driver->offset);

        if (triggerChannel != driver->timerChannel)
        {
            /* FIXME add IfxGtm_Tom_Ch_configurePwmMode() and use it */
            IfxGtm_Tom_Ch_setResetSource(driver->tom, triggerChannel, IfxGtm_Tom_Ch_ResetEvent_onTrigger);
            IfxGtm_Tom_Ch_setClockSource(driver->tom, triggerChannel, config->clock);
            IfxGtm_Tom_Ch_setTriggerOutput(driver->tom, triggerChannel, IfxGtm_Tom_Ch_OutputTrigger_forward);
            IfxGtm_Tom_Tgc_enableChannels(driver->tgc[0], triggerChannelMask, 0, FALSE);
            IfxGtm_Tom_Timer_addToChannelMask(driver, driver->triggerChannel);
        }
        else
        {}

        /* Signal must go out of the GTM even if the port outpout is not enabled */
        IfxGtm_Tom_Tgc_enableChannelsOutput(driver->tgc[0], triggerChannelMask, 0, FALSE);

        if (config->base.trigger.outputEnabled)
        {
            /* Initialize the port */
            IfxGtm_PinMap_setTomTout(config->triggerOut, config->base.trigger.outputMode, config->base.trigger.outputDriver);
        }
        else
        {}

        IfxGtm_Tom_Timer_setTrigger(driver, config->base.trigger.triggerPoint);
    }
    else
    {}

    /* Interrupt configuration */
    {
        volatile Ifx_SRC_SRCR *src;
        boolean                timerHasIrq   = config->base.isrPriority > 0;
        boolean                triggerHasIrq = (config->base.trigger.isrPriority > 0) && base->triggerEnabled;

        if (driver->triggerChannel == driver->timerChannel)
        {
            IfxGtm_Tom_Ch_setNotification(driver->tom, driver->timerChannel, timerHasIrq ? config->irqModeTimer : config->irqModeTrigger, timerHasIrq, triggerHasIrq);
            src = IfxGtm_Tom_Ch_getSrcPointer(driver->gtm, config->tom, driver->timerChannel);
            IfxSrc_init(src, timerHasIrq ? config->base.isrProvider : config->base.trigger.isrProvider, timerHasIrq ? config->base.isrPriority : config->base.trigger.isrPriority);
            /* FIXME ADD warning on interrupt setting in case timer and trigger uses the same channels or different channels, and in case only timer or trigger or both generates interrupts */
            IfxSrc_enable(src);
        }
        else
        {
            IfxGtm_IrqMode irqMode = IfxGtm_IrqMode_pulseNotify;

            if (timerHasIrq)
            {
                IfxGtm_Tom_Ch_setNotification(driver->tom, driver->timerChannel, irqMode, TRUE, FALSE);
                src = IfxGtm_Tom_Ch_getSrcPointer(driver->gtm, config->tom, driver->timerChannel);
                IfxSrc_init(src, config->base.isrProvider, config->base.isrPriority);
                IfxSrc_enable(src);
            }

            if (triggerHasIrq)
            {
                IfxGtm_Tom_Ch_setNotification(driver->tom, driver->triggerChannel, irqMode, FALSE, TRUE);
                src = IfxGtm_Tom_Ch_getSrcPointer(driver->gtm, config->tom, driver->triggerChannel);
                IfxSrc_init(src, config->base.trigger.isrProvider, config->base.trigger.isrPriority);
                IfxSrc_enable(src);
            }
        }
    }

    /* Transfer the shadow registers */
    IfxGtm_Tom_Tgc_setChannelsForceUpdate(driver->tgc[0], driver->channelsMask[0], 0, 0, 0);
    IfxGtm_Tom_Tgc_trigger(driver->tgc[0]);
    IfxGtm_Tom_Tgc_setChannelsForceUpdate(driver->tgc[0], 0, driver->channelsMask[0], 0, 0);
    return result;
}