/*********************************************************************
*                SEGGER MICROCONTROLLER GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
**********************************************************************
*                                                                    *
*        (c) 2003-2008     SEGGER Microcontroller GmbH & Co KG       *
*                                                                    *
*        Internet: www.segger.com    Support:  support@segger.com    *
*                                                                    *
**********************************************************************

----------------------------------------------------------------------
File    : Start_2TaskDisplay.c
Purpose : Sample program for OS running on Luminary LM3S3748-EK.
--------- END-OF-HEADER --------------------------------------------*/

#include "RTOS.h"
#include "formike128x128x16.h"
#include "grlib.h"

/*********************************************************************
*
*       Static data
*
**********************************************************************
*/
static OS_STACKPTR int _StackLP[1024];
static OS_TASK         _TCBLP;
static OS_RSEMA _SemaDisplay;
static OS_U8    _IsInited;
static tContext _sContext;

/*********************************************************************
*
*       Display module
*
*  Code (and data) in this section would most likely be placed in a
*  file of its own in a real application.
*
*********************************************************************/

void DISPLAY_String(const char * sText, unsigned int vPos, unsigned int hPos, tContext * pContext); // Avoid "No Prototype" warning
void DISPLAY_Init(void);                                                                            // Avoid "No Prototype" warning

/*********************************************************************
*
*             Local functions
*
**********************************************************************
*/

static void _InitIfRequired(void) {
  if (_IsInited == 0) {
    OS_CREATERSEMA(&_SemaDisplay);
    //
    // Initialize the display driver.
    //
    Formike128x128x16Init();
    //
    // Turn on the backlight.
    //
    Formike128x128x16BacklightOn();
    //
    // Initialize the graphics context.
    //
    GrContextInit(&_sContext, &g_sFormike128x128x16);
    GrContextForegroundSet(&_sContext, ClrWhite);
    GrContextFontSet(&_sContext, &g_sFontFixed6x8);
    GrStringDrawCentered(&_sContext, "embOS on LM3S3748", -1, GrContextDpyWidthGet(&_sContext) / 2, 25,  0);
    GrStringDrawCentered(&_sContext, "www.segger.com",    -1, GrContextDpyWidthGet(&_sContext) / 2, 35,  0);
    GrFlush(&_sContext);
  }
  _IsInited = 1;
}

static void _Lock(void) {
  _InitIfRequired();         // Perform automatic initialisation so that explicit call to _Init is not required
  OS_Use(&_SemaDisplay);
}

static void _Unlock(void) {
  _InitIfRequired();         // Perform automatic initialisation so that explicit call to _Init is not required
  OS_Unuse(&_SemaDisplay);
}

void DISPLAY_String(const char * sText, unsigned int vPos, unsigned int hPos, tContext * pContext) {
  _Lock();
  GrStringDraw(pContext, sText, -1, vPos, hPos, 0);
  GrFlush(pContext);
  _Unlock();
}

void DISPLAY_Init(void) {
  _InitIfRequired();
}

/*********************************************************************
*
*       Application program
*
*********************************************************************/

static void LPTask(void) {
  while (1) {
    GrContextForegroundSet(&_sContext, ClrWhite);
    DISPLAY_String("LP Task", 10, 48, &_sContext);
    OS_Delay(200);
    GrContextForegroundSet(&_sContext, ClrBlack);
    DISPLAY_String("LP Task", 10, 48, &_sContext);
    OS_Delay(200);
  }
}

/*********************************************************************
*
*       main
*
*********************************************************************/

/*********************************************************************
*
*       MainTask
*/
void MainTask(void);
void MainTask(void) {
  DISPLAY_Init();
  //
  // Create low priority task
  //
  OS_CREATETASK(&_TCBLP, "LP Task", LPTask,  50, _StackLP);
  while (1) {
    GrContextForegroundSet(&_sContext, ClrWhite);
    DISPLAY_String("HP Task", 10, 6, &_sContext);
    OS_Delay(50);
    GrContextForegroundSet(&_sContext, ClrBlack);
    DISPLAY_String("HP Task", 10, 6, &_sContext);
    OS_Delay(50);
  }
}


