This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3507: Timeline for silicon update to resolve the period capture issue

Part Number: MSPM0G3507
Other Parts Discussed in Thread: MSPM0C1104

Hi,

Is there a timeline for silicon update to resolve the period capture issue?

Thanks,

  • Hi Brian,

    Is there a reason that the workarounds mentioned in the linked post do not work for your application?

    Regards,
    Luke

  • HI Luke,

    Workaround 1 (Manual reset the timer) has an error due to the manual reset latency so is not effective at high frequencies. Workaround 2 (manual calculate the period) can work accurately but has a lot of additional code overhead in the ISR. I'm working on realtime systems so correct and accurate timer operation at high frequency is critical.

    Regards,

    Brian

       

  • Hi Brain,

    There is no current timeline for a device revision. I would recommend the software workaround to capture the period.

    If you want to cut down on the clock cycles to reduce the software overhead I would recommend getting the value straight from the register, or simply pulling the data out from the GPTIMER Regs. Same thing can happen with loading the load value for your timer.

    Here's an example I took to speed up the time it takes to pull the data.

    /*
     * Copyright (c) 2020, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include "ti_msp_dl_config.h"
    
    volatile uint32_t gCaptureCnt;
    volatile bool gSynced;
    volatile bool gCheckCaptures;
    uint32_t gLoadValue;
    
    volatile uint32_t start, end, calibration, time;
    
    int main(void)
    {
        volatile static uint32_t pwmPeriod;
        __attribute__((unused)) volatile static uint32_t pwmDuty;
    
        SYSCFG_DL_init();
    
        start = DL_SYSTICK_getValue();
        end = DL_SYSTICK_getValue();
        calibration = start - end;
    
        /*
         * This value is used to reload timer manually. Due to timer capture
         * limitation
         */
        gLoadValue = DL_TimerG_getLoadValue(CAPTURE_0_INST);
    
        /* Initialize capture global states */
        gSynced        = false;
        gCheckCaptures = false;
    
        /*
         * Forcing timers to halt immediately to prevent timers getting out of sync
         * when code is halted
         */
        DL_TimerG_setCoreHaltBehavior(
            CAPTURE_0_INST, DL_TIMER_CORE_HALT_IMMEDIATE);
        DL_TimerG_setCoreHaltBehavior(PWM_0_INST, DL_TIMER_CORE_HALT_IMMEDIATE);
    
        NVIC_EnableIRQ(CAPTURE_0_INST_INT_IRQN);
        DL_TimerG_startCounter(CAPTURE_0_INST);
        DL_TimerG_startCounter(PWM_0_INST);
    
        while (1) {
            while (false == gCheckCaptures) {
                __WFE();
            }
            gCheckCaptures = false;
    
            /*
             * Calculate PWM period and PWM duty cycle. IMPORTANT: These calculation
             * assume timer is running in DOWN counting mode
             */
            pwmPeriod = gLoadValue - gCaptureCnt;
            pwmDuty   = ((gLoadValue - DL_TimerG_getCaptureCompareValue(
                                         CAPTURE_0_INST, DL_TIMER_CC_0_INDEX)) *
                          100) /
                      pwmPeriod;
    
            __BKPT(0);
        }
    }
    
    void CAPTURE_0_INST_IRQHandler(void)
    {
        switch (DL_TimerG_getPendingInterrupt(CAPTURE_0_INST)) {
            case DL_TIMERG_IIDX_CC1_DN:
                if (gSynced == true) {
                start = DL_SYSTICK_getValue();
                //Getting the data from the struct directly, saves clock cycles
                gCaptureCnt = (CAPTURE_0_INST->COUNTERREGS.CC_01[1]) & GPTIMER_CC_01_CCVAL_MASK;
                    /*gCaptureCnt = DL_TimerG_getCaptureCompareValue(
                        CAPTURE_0_INST, DL_TIMER_CC_1_INDEX);*/
                end = DL_SYSTICK_getValue();
                    gCheckCaptures = true;
                } else {
                    gSynced = true;
                }
                /* Manual reload is needed to workaround timer capture limitation */
                DL_TimerG_setTimerCount(CAPTURE_0_INST, gLoadValue);
                time = start - end - calibration;
                break;
            case DL_TIMERG_IIDX_ZERO:
                /* If Timer reaches zero then no PWM signal is detected and it
                 * requires re-synchronization
                 */
                gSynced = false;
                break;
            default:
                break;
        }
    }
    

    You'll save some clock cycles by direct access, our driverlib has flexibility on your inputs (which timer, channel etc.) which can cause extra clock cycles to process this. By doing a direct access you will save that processing time.

    Regards,

    Luke

  • Thanks Luke. I'll try out the code. This error in the silicon really makes the timer difficult to use for real time systems. Seems crazy that this was not detected in validation and that there is no plan to fix the error. Anyway, i'll try get the part to do what is needed using the workaround for now. Hopefully the silicon will get updated at some point in the future and the timer will work as intended. Best regards, Brian

  • Hi Luke,

    I'm evaluating xMSPM0C1104 device and I also noticed that timer 'Period capture' functionality isn't working. There is no data about this in the Errata document on the ti.com. Can you confirm that MSPM0C family also has same issue.

    Regards,

    Goran

  • Hi Goran,

    I believe this will impact the MSPM0C1104 as well, but let me double check for you.

    Regards,
    Luke