Monday, December 17, 2012

Adding functionality to the Stellaris LaunchPad project0

This is a simple tutorial about how to expand the Stellaris LaunchPad project0 to expand the functionality a little. Perhaps this will guide somebody into advancing their knowledge.

Project0 is also known as the qs-rgb project. It is the project that ships installed on the Stellaris LaunchPad. This assumes you have installed and can use Code Composer Studio and StellarisWare Complete. If you have not imported the qs-rgb project, you can find it in the [StellarisWare root directory]/boards/ek-lm4f120xl/gs-rgb directory.

I am going to add functionality that will allow you to pause the LED on the current color or resume the cycling of the colors.

Let's start by opening  qs-rgb.h and defining a variable to hold the state of our pausing the application. We will add our variable to the sAppState_t struct. Modify the code starting at line 50 to the following:

//*****************************************************************************
//
// Structure typedef to make storing application state data to and from the
// hibernate battery backed memory simpler.
//      ulColors:       [R, G, B] range is 0 to 0xFFFF per color.
//      ulMode:         The current application mode, system state variable.
//      ulButtons:      bit map representation of buttons being pressed
//      ulManualIndex:  Control variable for manual color increment/decrement
//      fColorWheelPos: Control variable to govern color mixing
//      fIntensity:     Control variable to govern overall brightness of LED

//      usPauseState    Control variable to govern pausing of LED
//
//*****************************************************************************
typedef struct
{
    unsigned long ulColors[3];
    unsigned long ulMode;
    unsigned long ulButtons;
    unsigned long ulManualIndex;
    unsigned long ulModeTimer;
    float fColorWheelPos;
    float fIntensity;
    unsigned short usPauseState;

}sAppState_t;


Now, we will add a function declaration to the end of the file. Modify the code starting at line 92 to add the following:
extern void AppPause(void);




 We now move to qs-rgb.c.

The first thing to do is keep the documentation up to date. Add the following line at line number 70:
//! Command 'pause' will toggle the cycling of the LED.
  
We could set the usPauseState anywhere we want, but to keep the code cleaner, we will modify the value only within a function. That way, anything within the application could change the pause state by calling the method. Add the following function at the end of the functions before the main function. This could be added anywhere within gs-rgb.c file, but I put mine in at line 458.
//*****************************************************************************
//
// Uses the usPauseState variable to indicate the paused state of the LED
//
// This function is called when system has decided it is time to pause or
// resume the cycling of the LED
//
//*****************************************************************************
void
AppPause(void)
{
    if (g_sAppState == 0) {
        g_sAppState.usPauseState = 1;
    } else {
        g_sAppState.usPauseState = 0;
    }
}


We are not actually going to pause the application. We are just going to prevent the updating of the LED color values. We are going to do this within the SysTickIntHandler. This function is the main action handler for the LED. Whenever the system handler interupts, this function is called. We will just prevent the update of the LED depending on our bPauseState.
 void SysTickIntHandler(void) {

    static float x;

    g_sAppState.ulButtons = ButtonsPoll(0, 0);
    AppButtonHandler();

    if (g_sAppState.usPauseState != 0) {
        //
        // Auto increment the color wheel if in the AUTO mode. AUTO mode is when
        // device is active but user interaction has timed out.
        //
        if (g_sAppState.ulMode == APP_MODE_AUTO) {
            g_sAppState.fColorWheelPos += APP_AUTO_COLOR_STEP;
        }

        //
        // Provide wrap around of the control variable from 0 to 1.5 times PI
        //
        if (g_sAppState.fColorWheelPos > (APP_PI * 1.5f)) {
            g_sAppState.fColorWheelPos = 0.0f;
        }
        if (x < 0.0f) {
            g_sAppState.fColorWheelPos = APP_PI * 1.5f;
        }

        //
        //    Set the RGB Color based on current control variable value.
        //
        AppRainbow(0);
    }
}

The application is now ready to pause and resume the LED cycling. We now need to add the ability to communicate our desire to pause or resume the LED cycling.

We first need to add the function declaration of our communication function to the rgb_commands.h file. Add the following line to the end of the declared functions at line 58:
extern int CMD_resume (int argc, char **argv);

Next, we need to add the callback to actually allow our command to be part of the system. Open rgb_commands.c and add the following at line 45:
    {"pause",    CMD_pause,     " : Pause or resume the cycling of the LED"},

Now we needd to actually implement the function that our command will call. Enter the following at the end of rgb_commands.c:
//*****************************************************************************
//
// Command: pause
//
// Pause the cycling or resume the cycling of the LED
//
//*****************************************************************************
int
CMD_pause (int argc, char **argv)
{
    (void) argc;
    (void) argv;
    AppPause();

    return (0);
}


Our last thing to do is to set an initial value for our control variable. In the first lines of our main() method, we will ensure the variable is set to initially cycle the LED (anything that is not zero). Modify the main method as shown below:
int main(void) {
    unsigned long ulStatus;
    unsigned long ulResetCause;
    long lCommandStatus;

    // make sure the app is set to cycle the LED
    g_sAppState.usPauseState = 1;


Now if you run the application and connect with your terminal program, when you type 'help' you should see the following:

Notice that our new 'pause' command is now listed on our terminal.

If you type pause into your terminal the Stellaris LaunchPad will either pause the cycling of the LED or resume the cycling of the LED.

Notice that you can still set the intensity and rgb color of the LED even while it is paused.

This has been a very simple tutorial to hopefully help somebody start down the road of discovery.

No comments:

Post a Comment