CC2340R5: How to control single channel in LGPTimer driver?

Part Number: CC2340R5

Tool/software:

Hi teams,

I am using LGPTimer driver to output 3 channel PWM.

How can I control a single PWM channel? Specifically, after configuring the LGPTimer parameters and calling LGPTimerLPF3_open to initialize the driver, all three PWM channels are active. However, at certain times, I need to disable one of the channels (e.g., disable channel 2).

What I came up is to control the register directly, please see the code below. Is it the recommended way to achieve this functionality?

    LGPTimerLPF3_Handle lgptHandle;
    LGPTimerLPF3_Params params;
    uint32_t cntTargetVal = 48000 / 2;   // 1kHz PWM count in crystal of 48 MHz
    uint32_t chCompVal0    = cntTargetVal/2; // duty of 50%
    uint32_t chCompVal1    = cntTargetVal - cntTargetVal/10; // duty of 10%
    uint32_t chCompVal2    = cntTargetVal - cntTargetVal/20; // duty of 5%

    // Configure channels action
    LGPTimerLPF3_Params_init(&params);
    params.channelProperty[0].action = LGPTimerLPF3_CH_TOGGLE_ON_COMPARE_PERIODIC;
    params.channelProperty[1].action = LGPTimerLPF3_CH_TOGGLE_ON_COMPARE_PERIODIC;
    params.channelProperty[2].action = LGPTimerLPF3_CH_TOGGLE_ON_COMPARE_PERIODIC;

    // Open driver
    lgptHandle = LGPTimerLPF3_open(0, &params);

    // Set channel output signal period
    LGPTimerLPF3_setInitialCounterTarget(lgptHandle, cntTargetVal, false);

    // Set channel output signal duty cycle
    LGPTimerLPF3_setInitialChannelCompVal(lgptHandle, LGPTimerLPF3_CH_NO_0, chCompVal0, false);
    LGPTimerLPF3_setInitialChannelCompVal(lgptHandle, LGPTimerLPF3_CH_NO_1, chCompVal1, false);
    LGPTimerLPF3_setInitialChannelCompVal(lgptHandle, LGPTimerLPF3_CH_NO_2, chCompVal2, false);

    // Start the LGPTimer in up-down-periodic mode
    LGPTimerLPF3_start(lgptHandle, LGPTimerLPF3_CTL_MODE_UPDWN_PER);


    while(1)
    {
        usleep(100000);
        
        // Disable       
        HWREG(LGPT3_BASE | 0x000000C8) &= 0xFFFFFFF0;

        usleep(100000);
        // Enable
        HWREG(LGPT3_BASE | 0x000000C8) |= 0x0000000E;

    }
    

Thanks.

BR,

Connor.

  • Hello Connor,

    I took a look at your code, and ran it on my end and it works well, it; is this meant for a customer? 

    I had a similar ticket that tried to address the same issue but needed to modify the driver themselves in my case [TIDRIVERS-7004] CC2340R5 PWM multi-channel fix - Texas Instruments JIRA. 

    Thanks,
    Alex F

  • Hi Alex,

    is this meant for a customer? 

    Yes, they need to use all timer resources of CC2340. But they still find the limitation. Therefore, they need to control each channel PWM (e.g. press one button to enable channel, release button to disable).

    Well, I created this thread just for confirm of the riskBlush

    Is there any plan to support this functionality?

    Thanks,

    BR,

    Connor.

  • Hello Conor,

    Is there any plan to support this functionality?

    - I believe we may be able to use the above code snippet with some GPIO control to achieve what the customer needs.

    Thanks,
    Alex F

  • Hi Alex,

    Another issue found.

    The issue would be described like: while periodly opening the LGPTimer to generate the PWM, a wrong duty of the PWM will come up for some rounds . And then generate the correct duty of PWM.

    Could you please give me some tips to find the root cause of the picture shown issue? With the code snippet below. The red rectangles show the wrong duty PWM.

        LGPTimerLPF3_Handle lgptHandle;
        LGPTimerLPF3_Params params;
        uint32_t cntTargetVal = 48000 / 2 / 3;   // 1kHz PWM count in crystal of 48 MHz
        uint32_t chCompVal0    = cntTargetVal/2; // duty of 50%
        uint32_t chCompVal1    = cntTargetVal - cntTargetVal/10; // duty of 10%
        uint32_t chCompVal2    = cntTargetVal/10; // duty of 90%
        uint32_t time2   = 2000;
        
        while(1)
        {
            // Configure channels action
            LGPTimerLPF3_Params_init(&params);
            params.channelProperty[0].action = LGPTimerLPF3_CH_TOGGLE_ON_COMPARE_PERIODIC;
            params.channelProperty[1].action = LGPTimerLPF3_CH_TOGGLE_ON_COMPARE_PERIODIC;
            params.channelProperty[2].action = LGPTimerLPF3_CH_TOGGLE_ON_COMPARE_PERIODIC;
    
            // Open driver
            lgptHandle = LGPTimerLPF3_open(0, &params);
    
            // Set channel output signal period
            LGPTimerLPF3_setInitialCounterTarget(lgptHandle, cntTargetVal, false);
    
            // Set channel output signal duty cycle
            LGPTimerLPF3_setInitialChannelCompVal(lgptHandle, LGPTimerLPF3_CH_NO_0, chCompVal0, false);
            LGPTimerLPF3_setInitialChannelCompVal(lgptHandle, LGPTimerLPF3_CH_NO_1, chCompVal1, false);
            LGPTimerLPF3_setInitialChannelCompVal(lgptHandle, LGPTimerLPF3_CH_NO_2, chCompVal2, false);
    
            // Start the LGPTimer in up-down-periodic mode
            LGPTimerLPF3_start(lgptHandle, LGPTimerLPF3_CTL_MODE_UPDWN_PER);
            
            usleep(time2);
            
            // Disable
            LGPTimerLPF3_stop(lgptHandle);
            LGPTimerLPF3_close(lgptHandle);
            usleep(time2);
    
        }

    Actually, I found the “time2” delay time will Influence this issue(large time(>100ms) will not reproduce this issue).

    So, I need your helps.

    Thanks,

    BR,

    Connor.