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.

LAUNCHXL-CC26X2R1: PWM generation

Part Number: LAUNCHXL-CC26X2R1
Other Parts Discussed in Thread: SYSBIOS, Z-STACK

Hello,

i've few questions about pwm on CC2652R1F uc. 

I have to drive ws2813 leds with use of pwm. But as far as i know to the PWM driver from SDK doesn't work with DMA and there is no possibility to have some callback or interrupt when PWM period occurs.

So i decided to write my own PWM driver from scratch.  But i've some issues.

1. How can i map pin to work as PWM output. I don't see PORTID related to the GPT in reference manual:

2. How can i write my own interrupt handler. I couldn't find anywhere ISR vector table...
Or should i simply use TimerIntRegister() function as i have in my app.cfg following code: (i started with example project from sdk)

/*
 * Starting address to place the interrupt vector table.
 * Note: This is currently placed in RAM to allow for interrupts to be
 *     configured at runtime.
 */
/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */
m3Hwi.vectorTableAddress  = 0x20000000;


3. Can i use DMA without any special constraints? Maybe there are some limitatiions depending on Z-Stack or sysbios architecture.

Regards,

mf

  • Mateusz,

    1. Refer to the PWM documentation here: PWM.h and PWMTimerCC26XX.h. In PWMTimerCC26XX.h, you will see an example of PWMTimerCC26XX_HwAttrs which shows how to set up underlying PIN and GPTimer driver statically.

    2. Using TimerIntRegister() to register a handler based on a timer is probably the best way to handle this. You can use TimerIntRegister to point to the interrupt handler.

    3. Using DMA should'nt affect the stack directly -- Z-Stack itself doesn't use any serial interfaces, and doesn't copy large amounts of data between buffers

    Regards,

    Daniel

  • Hello Daniel,

    thanks for reply.

    After looking into PWM and GPTimers driver's source codes i am able, to enable interrupt related to the timer, by using function GPTimerCC26XX_registerInterrupt().
    But only one interrupt works, namely GPT_INT_CAPTURE (only for this enum interrupt is called).

    As i understand this interrupt relates to input capture (on edge) event and is not suitable for my purposes.

    This is the only one which works. Maybe should i not use drivers from sdk and write everything on my own?

    I tried to change PWM duty from that interrupt, but it is not working as expected.

    What i want achieve is to be able change duty after each period.

    My pwm period is 1.25us (800kHz), what i can see on oscilloscope is that, duty is changed but after about 24 periods.

    It will be nice if could you provide me the steps, how to configure timer interrupt to get one after each period.

    thanks and regards

  • Mateusz,

    To clarify, are you trying to trigger a timer interrupt based on your PWM period (which is 1.25µSec)? It's possible that the latency you are seeing is due to overhead from the drivers and RTOS. It might be useful if you could provide a timing diagram of what you are expecting on the output of the pin. 

    Regards,

    Daniel

  • Yes, generally i want to have an interrupt every 1.25uS and be able to change from it duty of my PWM signal.

    As i said i have to drive ws2813 leds with PWM signal. ws2813 uses protocol which codes 0s and 1s with width of the pulse, like shown below



    So if for example i want to send 110... to the led i need to have pwm output like this (sorry for quality):


    Or here i found another one:


    My idea is to use pwm + dma to minimalize use of cpu.
    I have done this for ws2812 with pwm, but on STM32 uC and on bare metal (without RTOS).

    Do you think i am able to achive this?

    EDIT:
    What i noticed is that you probaly are right and this latency is caused by RTOS. 

    I set int priority to the highest and wrote my own HWI routine. And what i can see is the delay has decrased to 2. periods (2.5 us).

    void PWM_registerInt(PWM_Handle handle, GPTimerCC26XX_HwiFxn isr){
    
        PWMTimerCC26XX_Object* obj = (PWMTimerCC26XX_Object*)handle->object;
        //GPTimerCC26XX_registerInterrupt(obj->hTimer, isr, GPT_INT_CAPTURE);
    
        GPTimerCC26XX_HWAttrs const* hwAttr = obj->hTimer->hwAttrs;
        GPTimerCC26XX_Object* timObj = obj->hTimer->object;
    
        //timObj->hwiCallbackFxn[obj->hTimer->timerPart] = isr;
        // construct RTOS hwi
    
        HwiP_Struct* pHwi = &timObj->hwi[obj->hTimer->timerPart];
        HwiP_Params params;
        HwiP_Params_init(&params);
        params.arg = (uintptr_t)obj->hTimer;
        params.enableInt = true;
        params.priority = 0;//(1<<5);
    
        HwiP_Handle h = HwiP_construct(pHwi, hwAttr->intNum, pwm_hwi, &params);
    
        GPTimerCC26XX_enableInterrupt(obj->hTimer, GPT_INT_CAPTURE);
    }
    
    
    static void pwm_hwi(uintptr_t arg0){
    
        const uint32_t timA_MIS_MASK = 0x000000FF;
        TimerMatchSet(GPT0_BASE, TIMER_A, 10);
    
        uint32_t timA_MIS = HWREG(GPT0_BASE + GPT_O_MIS);
        timA_MIS &= timA_MIS_MASK;
        // clear interrupt flag
        HWREG(GPT0_BASE + GPT_O_ICLR) = timA_MIS;
    }


    So my question now is, can i have interrupt handler directly from peripheral (i mean without using HWI)? Or will it have impact on the RTOS behaviour?

    Thanks and regards,

    mf

  • It could have an impact on the RTOS, especially the stacks (I see you tagged your post with ZSTACK).

    Another option could be to use SPI + DMA. There are a couple of examples of this on e2e and github.

    https://github.com/Lahorde/cc26xx_neopixel 

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/bluetooth-forum/507230/ws2812-neopixel-driver-on-cc26xx 

    Regards,

    Daniel

  • Hello Daniel,

    Sorry i didn't reply, but i was on sick leave and had no posibility to check your solution.

    Anyway i tried SPI + DMA and it worked for me. 

    So thank you for your help.

    Regards,

    mf