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.

Getting Started RGB PWM Question

Hi,

I'm a third year triple E student who's decided to try and learn the M4/stellaris architecture. I've had some experience with the motorola HCS08 but I find the API approach for this processor a bit confusing. I've only had the launchpad board for a couple of days but I've been following the TI labs and after completing lab4 - interrupts decided to try and drive the RGB led with PWM.

I've got the following code which almost works - all I'm trying to do at the minute is fade in each of the colours. I can get each of the colours to fade in individually, if i comment out all of the timer setup for the colours I'm not using, but if I try to fade all three in at the same time I get some weird behaviour - the colour is an off green (looking through the header files for the qs-rgb I've realised this is because "true white" is not 100% R,G,B) and there is no discernable fading - the LED is just instantly on.

Also, red and blue fade in reasonably reliably by themselves, but the green will fade in once, and if I reset the board the LED will not turn on again. I can fix this problem by uncommenting all of the timer setup, running it, and then commenting out the colours I don't want to use again, which leads me to think there must be something inherently wrong with my understanding of how to set up the timers - I remember reading a few times in the datasheet things like you must make sure to set x bit before writing to y register, or do not enable a peripheral before you've configured it - so I'm assuming I may be missing some critical understanding in an area such as this. The code I'm using is below - can anyone see any glaring errors in my approach?



#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h"


int main(void)
{

    unsigned long ulPeriod;
    unsigned long dutyCycleRed;
    unsigned long dutyCycleBlue;
    unsigned long dutyCycleGreen;


    ulPeriod = 1000;
    dutyCycleRed = ulPeriod;
    dutyCycleBlue = ulPeriod;
    dutyCycleGreen = ulPeriod;

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0 ); //added this because green led was on regardless of PWM configuration




    //red pin setup
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
    TimerLoadSet(TIMER0_BASE, TIMER_B, ulPeriod);
    TimerMatchSet(TIMER0_BASE, TIMER_B, dutyCycleRed);
    TimerEnable(TIMER0_BASE, TIMER_B);

    GPIOPinConfigure(GPIO_PF1_T0CCP1);
    GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_1);


    //blue pin setup
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);
    TimerLoadSet(TIMER1_BASE, TIMER_A, ulPeriod);
    dutyCycleBlue=ulPeriod;
    TimerMatchSet(TIMER1_BASE, TIMER_A, dutyCycleBlue);
    TimerEnable(TIMER1_BASE, TIMER_A);

    GPIOPinConfigure(GPIO_PF2_T1CCP0);
    GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_2);




    //green pin setup
    TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
    TimerLoadSet(TIMER1_BASE, TIMER_B, ulPeriod);
    TimerMatchSet(TIMER1_BASE, TIMER_B, dutyCycleGreen);
    TimerEnable(TIMER1_BASE,TIMER_B);

    GPIOPinConfigure(GPIO_PF3_T1CCP1);
    GPIOPinTypeTimer(GPIO_PORTF_BASE,GPIO_PIN_3);



while(1){
    dutyCycleRed--;
    dutyCycleBlue=1000; //attempt to turn off green and blue LEDs
    dutyCycleGreen=1000;
 

    TimerMatchSet(TIMER0_BASE,TIMER_B, dutyCycleRed);
    //TimerMatchSet(TIMER1_BASE,TIMER_A, dutyCycleBlue);
    //TimerMatchSet(TIMER1_BASE,TIMER_B, dutyCycleGreen);
    SysCtlDelay(100000);
    }
}


Also, when using the HCS08 I got used to reading the datasheet, finding the registers I needed to modify to achieve my desired behaviour, and writing to those memory addresses directly. I quite like this approach because I can follow what's actually going on at a hardware level - the API just feels like an extra layer of abstraction to learn. The datasheet does seem to reference how to set up PWM in this way - page 677-678 have instructions like "Write the GPTM Configuration (GPTMCFG) register with a value of 0x0000.0004". How do you actually achieve this in code composer? The HCS08 used CodeWarrior and if I remember rightly you just had to say

GPTMCFG = 0x0000.0004

but I tried this in CCS and it didn't work.

Any help anyone could give me would be massively appreciated!


  • It's only confusing till you figure it out.

    What does this mean? GPTMCFG = 0x0000.0004

    Not all of us know everything eh?

    // **********************


    This turns off all the lights...

     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0 )

     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x0E )

    The lights are on bits 1,2,4 -- not bit 0 (Zero) so the values are 2,4,8 as I recall Red, Blue, Green, PF1, Pf2, PF3

    This turns on only the light on PF3

     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x08 );  //did I get the Hex number right for the Green light?

    This turns off only the light on PF3

     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0 );


    If you OR all the pins -- all the lights can go on and off...

    0x02 and PF1 and GPIO_PIN_1 is the RED light...


    That should get you on your way.



  • I'm confused  - I thought the reason you used a timer was so you didn't have to write to the pins directly? I.e. as the timer was counting down the pin would be high, and the LED would be on, and once it reached its match value it would be low for the rest of the count. For instance, this code makes the red LED fade in:

        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
        
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0 ); //added this because green led was on regardless of PWM configuration


        //red pin setup
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
        TimerLoadSet(TIMER0_BASE, TIMER_B, ulPeriod);
        TimerMatchSet(TIMER0_BASE, TIMER_B, dutyCycleRed);
        TimerEnable(TIMER0_BASE, TIMER_B);

        GPIOPinConfigure(GPIO_PF1_T0CCP1);
        GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_1);

    while(1){

        dutyCycleRed--; //(equal to ulPeriod initially)

        TimerMatchSet(TIMER0_BASE, TIMER_B, dutyCycleRed);

    }

    and at no point have I had to write GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 2); to toggle it on or off?