A porting of a GPS decoding and presenting program within the mbos RTOS. It is not a definitive application but a study program to test NMEA full decoding library and a first approach to an RTOS. Many thanks to Andrew Levido for his support and his patience on teaching me the RTOS principles from the other side of the Earth. It uses NMEA library by Tim (xtimor@gmail.com) ported by Ken Todotani (http://mbed.org/users/todotani/) on public mbed library (http://mbed.org/users/todotani/programs/GPS_nmeaLib/5yo4h) also available, as original universal C library, on http://nmea.sourceforge.net

Dependencies:   mbos Watchdog TextLCD mbed ConfigFile

Files at this revision

API Documentation at this revision

Comitter:
guiott
Date:
Tue Jan 31 00:22:58 2012 +0000
Parent:
1:360c4a23cb1d
Child:
3:a2f9eb3b8a16
Commit message:
WDT optimized for reliability. A better organization of source code has be done separating each task in a dedicated module.

Changed in this revision

Common.h Show annotated file Show diff for this revision Revisions of this file
Init.h Show annotated file Show diff for this revision Revisions of this file
LeonardoMbos.cpp Show annotated file Show diff for this revision Revisions of this file
Prototype.h Show annotated file Show diff for this revision Revisions of this file
Startup.cpp Show annotated file Show diff for this revision Revisions of this file
Startup.h Show annotated file Show diff for this revision Revisions of this file
Task1Gps.cpp Show annotated file Show diff for this revision Revisions of this file
Task1Gps.h Show annotated file Show diff for this revision Revisions of this file
Task2Keypad.cpp Show annotated file Show diff for this revision Revisions of this file
Task2Keypad.h Show annotated file Show diff for this revision Revisions of this file
Task3Lcd.cpp Show annotated file Show diff for this revision Revisions of this file
Task3Lcd.h Show annotated file Show diff for this revision Revisions of this file
Task4LedBlink.cpp Show annotated file Show diff for this revision Revisions of this file
Task4LedBlink.h Show annotated file Show diff for this revision Revisions of this file
Task5SetTime.cpp Show annotated file Show diff for this revision Revisions of this file
Task5SetTime.h Show annotated file Show diff for this revision Revisions of this file
Task6Pc.cpp Show annotated file Show diff for this revision Revisions of this file
Task6Pc.h Show annotated file Show diff for this revision Revisions of this file
Task7Dim.cpp Show annotated file Show diff for this revision Revisions of this file
Task7Dim.h Show annotated file Show diff for this revision Revisions of this file
Task8Temp.cpp Show annotated file Show diff for this revision Revisions of this file
Task8Temp.h Show annotated file Show diff for this revision Revisions of this file
Task9Wdt.cpp Show annotated file Show diff for this revision Revisions of this file
Task9Wdt.h Show annotated file Show diff for this revision Revisions of this file
Tasks.h Show annotated file Show diff for this revision Revisions of this file
--- a/Common.h	Sun Jan 29 22:08:35 2012 +0000
+++ b/Common.h	Tue Jan 31 00:22:58 2012 +0000
@@ -6,4 +6,21 @@
 #define LCD_LIGHT_DIM_TIMER 5000
 #define SHOW_LCD_TIMER 500
 #define TEMP_TIMER 500
-#define WDT_TIMER 5
+#define WDT_TIMER 250
+#define WDT_TIMEOUT .3f
+
+
+typedef struct _DegMinSec
+{
+    int Deg;         
+    int Min; 
+    double Sec;        
+ } DegMinSec;
+
+typedef struct _DistAzimuth
+{
+    double Dist; 
+    double Azimuth[2];
+ } DistAzimuth;
+ 
+ enum DirLab{Mag, Dir, Gps};
\ No newline at end of file
--- a/Init.h	Sun Jan 29 22:08:35 2012 +0000
+++ b/Init.h	Tue Jan 31 00:22:58 2012 +0000
@@ -1,52 +1,18 @@
-// Ports initialization
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-Serial pc(USBTX, USBRX);
-Serial gps(NC, GPSRX);
-
-PwmOut LcdBklight(p25);
-AnalogIn KeypadIn(p20);
+extern Serial pc;
+extern Watchdog wd;
 
 // Globals
-int size;
 int X=0, Y=0;
-char Key='-';
-
-char msgBuff[2][BUFF_SIZE];     // Receive data buffer from GPS module
-                                // Two buffer for double buffering
-volatile int writePointer = 0;  // Write pointer for active data buffer
-volatile unsigned int bufferSelect = 0; // Active buffer selector
 
-double latitude, longitude;
-double degrees, minutes;
+extern double latitude, longitude;
+extern double degrees, minutes;
 
-int SetTimeOk=0; // is RTC in sync?
-int PcMonitor=0;    // to control serial out on USB serial
-int Menu = 0;
-const char *Lab[]={"MAG", "DIR", "GPS"}; //Label to display in compass view
-int CmpPos[]={0,15,0}; //Compass position
-int Ang[3]; //Compass angle values
-enum DirLab{Mag, Dir, Gps};
+extern int SetTimeOk;
 
-nmeaINFO info;                  // Store GPS information 
-nmeaPARSER parser;
-
-typedef struct _DegMinSec
-{
-    int Deg;         
-    int Min; 
-    double Sec;        
- } DegMinSec;
+extern nmeaINFO info; 
+extern nmeaPOS Pos[];
+extern DistAzimuth Path;
+extern nmeaINFO Dest;
+extern int Menu;
 
-typedef struct _DistAzimuth
-{
-    double Dist; 
-    double Azimuth[2];
- } DistAzimuth;
-  
- DistAzimuth Path;
- nmeaPOS Pos[2];
- nmeaINFO Dest;
- 
+extern int Ang[];
--- a/LeonardoMbos.cpp	Sun Jan 29 22:08:35 2012 +0000
+++ b/LeonardoMbos.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -61,15 +61,11 @@
 #include <string>
 #include "TextLCD.h"
 #include "nmea/nmea.h"
+#include <Watchdog.h>
 #include "Init.h" 
 #include "Prototype.h"
 #include "mbos.h"
 #include "Tasks.h"
-#include <Watchdog.h>
-
-TextLCD lcd(p12, p11, p24, p23, p22, p21, TextLCD::LCD20x4); // rs, e, d4-d7
-
-Watchdog wd;
 
 // Set up RTOS;
 mbos os(NUM_TASKS, NUM_TIMERS, NUM_RESOURCES);
@@ -81,13 +77,23 @@
     {
         pc.printf("Watchdog caused reset**********************************\r\n");
     }
-    wd.Configure(WDT_TIMER);       // sets the timeout interval
+    wd.Configure(WDT_TIMEOUT);       // sets the timeout interval
 
     os.Start(); // the RTOS starts now
 }
 
 //functions =====================================================================
 
+void mbosIdleTask(void)
+{/**
+ *\brief TASK 0 watchdog kick
+ */
+ while(1)
+ {
+
+ }
+}
+
 int CmpRead(void)
 {/**
  *\brief Magnetic Compass reading 
@@ -99,850 +105,3 @@
     return(Cmp);
 }
 
-void mbosIdleTask(void)
-{/**
- *\brief TASK 0 watchdog kick
- */
- while(1)
- {
-    wd.Service();       // kick the dog before the timeout
- }
-}
-
-void TempTask(void)
-{/**
- *\brief TASK 8 used to temporary test some functions 
- */
- static int TempAng;
- while (1)
- {
-  os.WaitEvent(TEMP_EVT); 
-  
-  if((TempAng+=5) >=360)
-  {
-    TempAng=0;
-  }
-  Ang[Mag]=TempAng;
-  Ang[Dir]=360-TempAng;
-  Ang[Gps]=180-TempAng;
-  printf("%i %i  %i \n", Ang[0], Ang[1], Ang[2]);
- }
-}
-
-void GpsStringParse(void)
-{/**
- *\brief parse the GPS string to extract info
- */
-    gps.attach(NULL);   // Suspend serial interrupt while buffer change
-    size = writePointer;
-    writePointer = 0;
-    bufferSelect++;     // Change buffer
-    gps.attach( &GpsSerialIsr );  // Resume serial interrupt
-    nmea_parse(&parser, msgBuff[(bufferSelect-1)&1], size, &info);
-    Coordinates(); // transform nmea coordinates in decimal degrees
-}
-
-void GpsDist(void)
-{/**
- *\brief compute the distance and direction (forward and reverse) 
-    from point A to point B on the ellipsoid
- */
-  
-    nmea_info2pos(&info, &Pos[0]);  // current position  
-    nmea_info2pos(&Dest, &Pos[1]);  // destination 
-
-    Path.Dist = nmea_distance_ellipsoid(&Pos[0], &Pos[1], &Path.Azimuth[1], &Path.Azimuth[0]);
-
-    if(Path.Azimuth[0] > NMEA_PI) 
-    {// reverse direction
-        Path.Azimuth[0] = Path.Azimuth[0] - NMEA_PI; 
-    }
-    else
-    {
-        Path.Azimuth[1] = Path.Azimuth[1] + NMEA_PI; 
-    }
-
-    for(int i=0; i < 2; i++)
-    {
-        Path.Azimuth[i]=(nmea_radian2degree(Path.Azimuth[i]));
-        if(Path.Azimuth[i] > 360)
-        {
-            Path.Azimuth[i] = Path.Azimuth[i] - 360;
-        }
-        if(Path.Azimuth[i] < 0)
-        {
-            Path.Azimuth[i] = Path.Azimuth[i] + 360;
-        }
-    }
-}
-
-void LcdLightDimTask(void)
-{/** 
- *\brief TASK 7, control the LCD backlight intensity to smoothly
-         switch it on or off
- */
- static float LightVal=1;
-        
- while(1)
- {       
-    os.WaitEvent(LCD_LIGHT_DIM_ON_EVT | LCD_LIGHT_DIM_OFF_EVT); 
-    if(os.GetEvent()==LCD_LIGHT_DIM_ON_EVT)
-    {
-      if(LightVal<1)
-      {
-        for (LightVal=0; LightVal<=1; LightVal+=0.01f)
-        {
-            LcdBklight=LightVal;
-            wait_ms(10);
-        }
-      }
-    // Set the timer for the power saving backlight switch off
-    os.ClearTimer(LCD_LIGHT_DIM_OFF_TMR);
-    os.SetTimer(LCD_LIGHT_DIM_OFF_TMR, LCD_LIGHT_DIM_TIMER, 0);
-    }
-    else if(os.GetEvent()==LCD_LIGHT_DIM_OFF_EVT)
-    {// The dimming off is slower than lighting up
-        for (LightVal=1; LightVal>=0; LightVal-=0.01f)
-        {
-            LcdBklight=LightVal;           
-            wait_ms(30);
-        }        
-    }
- }
-}
-
-void Coordinates(void)
-{/**
- *\brief transform nmea coordinates in decimal degrees
- */
-    degrees = trunc(info.lat / 100.0);
-    minutes = info.lat - (degrees * 100.0);
-    latitude = degrees + minutes / 60.0;
-    degrees = trunc(info.lon / 100.0);
-    minutes = info.lon - (degrees * 100.0);
-    longitude = degrees + minutes / 60.0;
- }
-  
-void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec)
-{/**
- *\brief convert decimalDeg to Deg Min decimalSec
- */
-    DecSec->Deg = trunc(DecDeg);
-    double MinDec = (DecDeg - DecSec->Deg);
-    DecSec->Min = trunc(MinDec * 60);
-    DecSec->Sec = (MinDec * 3600) - (DecSec->Min * 60);
- }
-   
-void ShowPcTask(void) 
-{/**
- *\brief TASK 6, if a PC is connected, debug information can be sent to the console
- */
- static int it = 0;
- int i;
- DegMinSec DecCoord;
-    
- os.SetTimer(SHOW_PC_TMR, 1000, 1000);
- while(1)
- {
-    os.WaitEvent(SHOW_PC_EVT); 
-
-    if(pc.readable())
-    {// wait for an input
-        PcMonitor = (pc.getc()-48); // digit a number to en/dis-able debug
-     }
-     
-    if( PcMonitor==1 || PcMonitor>5)
-    {// Display Info parameters 
-        pc.printf(
-        "%03d, Lat: %f, Lon: %f, Sig:%d, Fix:%d, Inuse:%d\r\n",
-        it++, latitude, longitude, info.sig, info.fix, info.satinfo.inuse );
-        for (i = 0; i < NMEA_MAXSAT; i++) 
-            {
-            if (info.satinfo.sat[i].sig > 0)
-            pc.printf("  sat_id:%02d, sig:%02d, Inuse:%d\r\n",
-                      info.satinfo.sat[i].id , info.satinfo.sat[i].sig, 
-                      info.satinfo.sat[i].in_use);
-            }
-        pc.printf("\r\n");
-    }
-    
-    if( PcMonitor==2 || PcMonitor>5)
-    {// Display Distance parameters 
-        Deg2DegMinSec(nmea_radian2degree(Pos[0].lat), &DecCoord);
-        pc.printf("Lat1:%d %d\'%.3f\"  ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
-        Deg2DegMinSec(nmea_radian2degree(Pos[0].lon), &DecCoord);
-        pc.printf("Lon1:%d %d\'%.3f\"  ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
-        Deg2DegMinSec(nmea_radian2degree(Pos[1].lat), &DecCoord);
-        pc.printf("Lat2:%d %d\'%.3f\"  ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
-        Deg2DegMinSec(nmea_radian2degree(Pos[1].lon), &DecCoord);
-        pc.printf("Lon2:%d %d\'%.3f\"  \n", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
-        pc.printf("Dist:%f  Azimuth Start:%f  Azimuth Final:%f \n\n",
-                  Path.Dist, Path.Azimuth[0], Path.Azimuth[1]); 
-    }
-  }   
-}
-
-void ShowLcdTask(void)
-{/**
- *\brief TASK 3, display desired data on LCD
- */
- 
- static int Previous=0;
-
- os.SetTimer(SHOW_LCD_TMR, SHOW_LCD_TIMER, 0);
- while(1)
- {
- os.WaitEvent(SHOW_LCD_EVT);
-
-    if(Previous != Menu)
-    {// clear the display when function changes
-        lcd.cls();
-        Previous=Menu;
-    }
-    
-    switch(Menu)
-    {
-        case 0:
-            showSatLcd();
-            Previous=0;
-            break;
-            
-        case 1:
-            if(info.sig != 0)
-            {
-                showInfoLcd();
-            }
-            else
-            {
-                showSatLcd();
-            }
-            Previous=1;    
-            break;
-        
-        case 2:
-            showMenuLcd();
-            Previous=2;    
-            break;
-            
-        case 3:
-            showMenuLcd1();
-            Previous=3;    
-            break;  
-            
-        case 4: 
-            ShowPathLcd();
-            Previous=4;    
-            break; 
-            
-        default:
-            showInfoLcd();
-            break;
-    }
-    //restart timer for other options
-    os.SetTimer(SHOW_LCD_TMR, SHOW_LCD_TIMER, 0); 
- }
-}
-
-void ShowPathLcd(void)
-{
-    static int ChooseDir=0;
-    DegMinSec DecCoord;
-
-    Ang[Gps]=info.direction;
-    Ang[Mag]=CmpRead()-info.declination; //Compass reading corrected by declination
-    Ang[Dir]=Path.Azimuth[0];
-
-    ChooseDir++;
-    if(ChooseDir<7)
-    {
-        showDirLcd(Mag);
-    }
-    else if(ChooseDir>=7 && ChooseDir<12)
-    {
-        showDirLcd(Gps);
-    }
-    else if(ChooseDir>=12)
-    {
-       ChooseDir=0;
-    }
-    showDirLcd(Dir);
-    
-    Deg2DegMinSec(nmea_ndeg2degree(Dest.lat), &DecCoord);
-    lcd.locate(6,0);
-    lcd.printf("%d%d\'%.0f", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
-    lcd.printf("%c", Dest.lat >= 0 ? 'N': 'S');  
-    
-    Deg2DegMinSec(nmea_ndeg2degree(Dest.lon), &DecCoord);
-    lcd.locate(6,1);
-    lcd.printf("%d%d\'%.0f", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
-    lcd.printf("%c", Dest.lon >= 0 ? 'E': 'W');  
-    
-    lcd.locate(6,2);
-    lcd.printf(" dist m");
-    lcd.locate(6,3);
-    lcd.printf("%4.3f",Path.Dist);
-    
-
-}
-
-void showDirLcd(int Indx)
-{/**
- *\brief  display a sort of compass on LCD
- */
-    int Angle;
-
-    Angle=Ang[Indx]/18;
-
-    lcd.locate(CmpPos[Indx],0);
-    lcd.printf("  %c  ",0xA5);
-    lcd.locate(CmpPos[Indx],1);
-    lcd.printf("%c   %c",0xA5, 0xA5);
-    lcd.locate(CmpPos[Indx],2);
-    lcd.printf("%c   %c",0xA5, 0xA5);
-    lcd.locate(CmpPos[Indx],3);
-    lcd.printf("  %c  ",0xA5);
-    
-    lcd.locate(CmpPos[Indx]+1,1);
-    lcd.printf(Lab[Indx]);
-    lcd.locate(CmpPos[Indx]+1,2);
-    lcd.printf("%03i",Ang[Indx]);
-        
-    switch (Angle)
-    {
-        case 0:
-            lcd.locate(CmpPos[Indx]+2,0);
-            lcd.printf("%c",0xFF);
-            break;
-        case 1:
-            lcd.locate(CmpPos[Indx]+2,0);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+3,0);
-            lcd.printf("%c",0xFF);
-            break;
-        case 2:
-            lcd.locate(CmpPos[Indx]+3,0);
-            lcd.printf("%c",0xFF);
-            break;        
-        case 3:
-            lcd.locate(CmpPos[Indx]+3,0);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+4,1);
-            lcd.printf("%c",0xFF);
-            break;        
-        case 4:
-            lcd.locate(CmpPos[Indx]+4,1);
-            lcd.printf("%c",0xFF);
-            break;
-        case 5:       
-            lcd.locate(CmpPos[Indx]+4,1);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+4,2);
-            lcd.printf("%c",0xFF);
-            break;
-        case 6:   
-            lcd.locate(CmpPos[Indx]+4,2);
-            lcd.printf("%c",0xFF);
-            break;
-        case 7:       
-            lcd.locate(CmpPos[Indx]+4,2);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+3,3);
-            lcd.printf("%c",0xFF);
-            break;
-        case 8:   
-            lcd.locate(CmpPos[Indx]+3,3);
-            lcd.printf("%c",0xFF);
-            break;
-        case 9:       
-            lcd.locate(CmpPos[Indx]+3,3);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+2,3);
-            lcd.printf("%c",0xFF);
-            break;
-        case 10:   
-            lcd.locate(CmpPos[Indx]+2,3);
-            lcd.printf("%c",0xFF);
-            break;     
-        case 11:       
-            lcd.locate(CmpPos[Indx]+2,3);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+1,3);
-            lcd.printf("%c",0xFF);
-            break;
-        case 12:   
-            lcd.locate(CmpPos[Indx]+1,3);
-            lcd.printf("%c",0xFF);
-            break;     
-        case 13:       
-            lcd.locate(CmpPos[Indx]+1,3);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+0,2);
-            lcd.printf("%c",0xFF);
-            break;
-        case 14:   
-            lcd.locate(CmpPos[Indx]+0,2);
-            lcd.printf("%c",0xFF);
-            break;  
-        case 15:       
-            lcd.locate(CmpPos[Indx]+0,2);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+0,1);
-            lcd.printf("%c",0xFF);
-            break;
-        case 16:   
-            lcd.locate(CmpPos[Indx]+0,1);
-            lcd.printf("%c",0xFF);
-            break;  
-        case 17:       
-            lcd.locate(CmpPos[Indx]+0,1);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+1,0);
-            lcd.printf("%c",0xFF);
-            break;   
-        case 18:   
-            lcd.locate(CmpPos[Indx]+1,0);
-            lcd.printf("%c",0xFF);
-            break;  
-        case 19:       
-            lcd.locate(CmpPos[Indx]+1,0);
-            lcd.printf("%c",0xFF);
-            lcd.locate(CmpPos[Indx]+2,0);
-            lcd.printf("%c",0xFF);
-            break;   
-    }
-}
-
-void showMenuLcd(void)
-{/**
- *\brief  display a selection menu on LCD
- */
-    lcd.locate(0,0);
-    lcd.printf("1 - item 1");
-    lcd.locate(0,1);
-    lcd.printf("2 - item 2");
-    lcd.locate(0,2);
-    lcd.printf("3 - item 3");
-    lcd.locate(0,3);
-    lcd.printf("4 - item 4");    
-}
-
-void showMenuLcd1(void)
-{/**
- *\brief  display a selection menu on LCD
- */
-    lcd.locate(0,0);
-    lcd.printf("5 - item 5");
-    lcd.locate(0,1);
-    lcd.printf("6 - item 6");
-    lcd.locate(0,2);
-    lcd.printf("7 - item 7");
-    lcd.locate(0,3);
-    lcd.printf("8 - item 8");    
-}
-
-void showSatLcd(void) 
-{/**
- *\brief displays satellite informations
- */
-    for (int i = 0; i < NMEA_MAXSAT; i++) 
-    {
-        if(info.satinfo.sat[i].id < 20)
-        {
-            lcd.locate((info.satinfo.sat[i].id % 20) - 1,0);
-        }
-        else
-        {
-            lcd.locate((info.satinfo.sat[i].id % 20) - 1,1);    
-        }
-        
-        if (info.satinfo.sat[i].sig > 0)
-        {
-            lcd.printf("%d",info.satinfo.sat[i].sig/10);
-        }
-        else
-        {
-            lcd.printf(" ");    
-        }                   
-    }
-    lcd.locate(0,2);
-    lcd.printf("12345678901234567890");
-    lcd.locate(0, 3);
-    lcd.printf("P%2.1f H%2.1f V%2.1f %iD",
-    info.PDOP, info.HDOP, info.VDOP,info.fix);
-}    
-    
-void showInfoLcd(void) 
-{/**
- *\brief Show nmea info on LCD 
- */
-
-//    static int lastSat = 0;
-//    int satInview = 0;
-
- if(info.sig != 0)
- { 
-    lcd.locate(0, 0);
-    lcd.printf("%2.5f%c %3.5f%c",
-            latitude, info.lat >= 0 ? 'N': 'S',  
-            longitude, info.lon >= 0 ? 'E': 'W');
-  
-    lcd.locate(0, 1);
-    lcd.printf("H%.0f D%.0f_%.1f %iD", info.elv, info.direction, info.declination, info.fix);
-
-    lcd.locate(0, 2);
-    lcd.printf("P%2.1f H%2.1f V%2.1f S%i/%i",
-        info.PDOP, info.HDOP, info.VDOP, info.satinfo.inuse, info.satinfo.inview);
-        
-   /* lcd.locate(0, 3);
-    lcd.printf("%02d-%02d-%04d %02d:%02d:%02d ", 
-        info.utc.day, info.utc.mon + 1, info.utc.year + 1900,
-        info.utc.hour, info.utc.min, info.utc.sec); // Display JST (UTC + 9)
-   */
-
-/*
-    lcd.locate(0, 5);
-    for (int i = 0; i < NMEA_MAXSAT; i++) {
-        if (info.satinfo.sat[i].sig > 0) {
-            satInview++;
-            lcd.printf("  sat_id:%02d, sig:%02d, Inuse:%d \n",
-                      info.satinfo.sat[i].id , info.satinfo.sat[i].sig,
-                      info.satinfo.sat[i].in_use);
-        }
-    }
-    for (int j = satInview; j <= lastSat; j++)
-        lcd.printf("                             \n");     // delete line
-    lastSat = satInview;
- */
- 
- } 
- else
- {
-    lcd.cls();
-    lcd.locate(0,0);
-    lcd.printf("NO FIX"); 
- }
-
- // Grab a snapshot of the current RTC time.
- time_t seconds = time(NULL);
- char buffer[32];
- if((info.sig != 0)&&(SetTimeOk!=0))  
- {
-    strftime(buffer, 32, "%x %X", localtime(&seconds));
- }
- else
- {// if GPS time not valid doesn't display seconds
-     strftime(buffer, 32, "%x %H:%M", localtime(&seconds));
-     SetTimeOk = 0; // RTC was not set to a valid time 
- }
- lcd.locate(0,3);
- lcd.printf("%s", buffer);
-}
-
-void SetTimeTask(void)
-{/**
- *\brief TASK 5, Set RTC system time if the GPS time is valid
- */
- struct tm t;
- 
- os.SetTimer(SET_TIME_TMR, 60000, 60000);
- while(1)
- {  
- os.WaitEvent(SET_TIME_EVT);
-
-    if(info.sig != 0)    
-    {
-       t.tm_mday=info.utc.day;
-       t.tm_mon=info.utc.mon;
-       t.tm_year=info.utc.year; 
-       t.tm_hour=info.utc.hour;
-       t.tm_min=info.utc.min;
-       t.tm_sec=info.utc.sec;        
-          
-        time_t seconds = mktime(&t);       
-        set_time(seconds);
-        
-        SetTimeOk = 1; // RTC was set 
-    }
- }    
-}
-
-void LedBlinkTask(void)
-{/**
- *\brief TASK 4
-         LED 1: Quick blink=NOT fix, Slow blink=fix OK  
-         LED 2: blinks proportionally to HDOP
-         LED 3: blinks proportionally to VDOP
- */
-
- static int LedCnt1=0;
- //    static int LedCnt2=0;
- int OnH=0;
- int OnV=0;
-
- #define MAX 20
-  
- os.SetTimer(LED_BLINK_TMR, 100, 100);
-
- while(1)
- {
-    os.WaitEvent(LED_BLINK_EVT);
-            
-    if((info.HDOP>0)&&(info.HDOP<=2))
-    {
-        OnH=2;
-    }
-    else if((info.HDOP>2)&&(info.HDOP<=4))
-    {
-        OnH=4;    
-    }
-    else if((info.HDOP>4)&&(info.HDOP<=6))
-    {
-        OnH=6;    
-    }
-    else if((info.HDOP>6))
-    {
-        OnH=MAX/2;    
-    }        
-
-    if((info.VDOP>0)&&(info.VDOP<=2))
-    {
-        OnV=2;
-    }
-    else if((info.VDOP>2)&&(info.VDOP<=4))
-    {
-        OnV=4;    
-    }
-    else if((info.VDOP>4)&&(info.VDOP<=6))
-    {
-        OnV=6;    
-    }
-    else if((info.VDOP>6))
-    {
-        OnV=MAX/2;    
-    } 
-           
-    if(info.sig == 0)
-    {
-        led1=!led1;
-        led2=0;
-        led3=0;
-    }
-    else
-    {
-       if(LedCnt1<=MAX/2)
-       {
-            LedCnt1++;
-            led1=0;
-            if(LedCnt1<OnH)
-            {
-               led2=!led2; 
-            }
-            else 
-            {
-                led2=0;
-            }    
-            
-            if(LedCnt1<OnV)
-            {
-               led3=!led3; 
-            }
-            else 
-            {
-                led3=0;
-            }          
-       } 
-       else if((LedCnt1>MAX/2)&&(LedCnt1<=MAX))
-       {
-            LedCnt1++;
-            led1=1;
-            led2=0;
-            led3=0;
-       }
-       else if(LedCnt1>MAX)
-       {
-            LedCnt1=0;       
-       }
-    }
- }
-}
-
-
-void KeypadTask(void)
-{/**
- *\brief TASK 2, Keypad management. 
-         It uses just one ADC port. Five keys switch a 5 resistor ladder
-         obtaining a unique voltage for each key, with a priority that 
-         depends from the position of the resistor in the ladder.
-         This function makes an average of 50 analog values (50ms) before 
-         confirming the output, to filter out some noise and debounce keys
- */
-
-    static float KeypadAcc;         // accumulator to compute average
-    static float KeypadPrev;        // previous value to compute variation 
-    static int KeypadCount;         // all samples number
-    static int KeypadRealCount;     // valid samples only
-    float KeypadVal;  
-    static char KeyPrev='-';
-    
-    os.SetTimer(KEYPAD_TMR, 1, 1);
-    while(1)
-    {
-        os.WaitEvent(KEYPAD_EVT);
-        float InValue = KeypadIn.read();
-        if ((InValue > 0.3) && (abs(InValue - KeypadPrev) < 0.1))
-        {// makes the average only of the values above a threshold 
-         // and within an almost stable range
-            KeypadAcc+=InValue;
-            KeypadRealCount++;
-        }
-            
-        KeypadCount++;
-        KeypadPrev=InValue;
-    
-        if (KeypadCount >=50)
-        {
-            if(KeypadRealCount > 25)
-            {
-                KeypadVal=KeypadAcc/KeypadRealCount;
-            }
-            else
-            {// not enough values to average
-    
-                KeypadVal=0;
-            }
-           
-            KeypadAcc=0;
-            KeypadCount=0;
-            KeypadRealCount=0;
-         
-            if(KeypadVal <0.15)
-            {
-                Key='-';
-            }
-            else if(KeypadVal>=0.3 && KeypadVal<0.35)
-            {
-                Key='E';
-            }
-            else if(KeypadVal>=0.42 && KeypadVal<0.50)
-            {
-                Key='v';
-            }
-            else if(KeypadVal>=0.60 && KeypadVal<0.65)
-            {
-                Key='^';
-            }
-            else if(KeypadVal>=0.74 && KeypadVal<0.78)
-            {
-                Key='>';
-            }        
-            else if(KeypadVal>=0.85)
-            {
-                Key='<';
-            }
-            
-            if (Key!='-' && Key!=KeyPrev)
-            {// switch on the LCD backlight if key pressed
-                os.SetEvent(LCD_LIGHT_DIM_ON_EVT, LCD_LIGHT_DIM_TASK);
-            }
-            KeyPrev=Key;
-            switch (Key)
-            {
-                case '^':
-                    Menu=0;
-                break;
-     
-                case '>':
-                    Menu=1;
-                break;           
-     
-                case 'v':
-                    Menu=2;
-                break;
-                
-                case '<':
-                    Menu=3;
-                break;
-                
-                case 'E':
-                    Menu=4;
-                break;
-            }     
-       }
-   } 
-}
-
-void trace_h(const char *str, int str_size) 
-{/**
- *\brief output on console what's received on GPS serial
-          Callback function for NMEA parser buffer trace
- */
-    if( PcMonitor==5 || PcMonitor>5)
-    {
-        for (int i = 0; i < str_size; i++)
-        {
-            pc.putc(*str++);
-        }        
-    }
-}
-
-void error_h(const char *str, int str_size) 
-{/**
- *\brief Callback function for NMEA parser error
- */
-    for (int i = 0; i < str_size; i++)
-    {
-        pc.putc(*str++);
-    }    
-}
-
-void GpsSerialTask(void) 
-{/**
- *\brief TASK 1, wait for the event then get the input char
- */
- while(1)
- {
-    os.WaitEvent(GPS_SERIAL_IN_EVT);
-    GpsStringParse();
-            
-    Dest.lat= 4151.32496; // ***************debug
-    Dest.lon= 1229.34; // *************debug
-
-    GpsDist();
- }
-}
-
-void GpsSerialIsr(void) 
-{/**
- *\brief Interrupt handler for serial Rx
-         set the event for the serial task
- */
-    char c = gps.getc();
-    msgBuff[bufferSelect & 1][writePointer] = c;
-    if (writePointer++ == BUFF_SIZE)
-    {
-        writePointer = 0;
-    }
-    if (writePointer > 200) 
-    {// GPS input buffer full, start computing coordinates
-        os.SetEvent(GPS_SERIAL_IN_EVT, GPS_SERIAL_TASK);
-    }
-}
-
-double trunc(double v) 
-{/**
- *\brief Return nearest integer vaule less than input
- *
- *\parameters double variable to get nearest ingeger
- *
- *\return double 
- */
-    if(v < 0.0) 
-    {
-        v*= -1.0;
-        v = floor(v);
-        v*=-1.0;
-    } else {
-        v = floor(v);
-    }
-    return v;
-}
--- a/Prototype.h	Sun Jan 29 22:08:35 2012 +0000
+++ b/Prototype.h	Tue Jan 31 00:22:58 2012 +0000
@@ -1,27 +1,14 @@
 //================= Prototypes =================
-void ShowPathLcd(void);
-int CmpRead(void);
-void TempTask(void);
-void LcdLightDimTask(void);
 void Initialize (void);
 int TimerStart(void);
 void TimerStop(int Tstart, int Index);
-void GpsStringParse(void);
-void GpsDist(void);
+
+//GPS
 void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec);
-void GpsDist(void);
-void showDirLcd(int Indx);
-void showMenuLcd1(void);
-void showMenuLcd(void);
-void showSatLcd(void);
+
 void SetTime(void);
-void Coordinates(void);
 void LedBlink(void);
-void GpsSerialIsr(void);
-void showInfoLcd(void);
 void showInfoPc(void);
-void trace_h(const char *str, int str_size);
-void error_h(const char *str, int str_size);
-double trunc(double v);
+
 //===============================================
 
--- a/Startup.cpp	Sun Jan 29 22:08:35 2012 +0000
+++ b/Startup.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -41,6 +41,7 @@
 os.CreateTask(SHOW_PC_TASK, SHOW_PC_PRIORITY, SHOW_PC_STACK_SZ, ShowPcTask);
 os.CreateTask(LCD_LIGHT_DIM_TASK, LCD_LIGHT_DIM_PRIORITY, LCD_LIGHT_DIM_STACK_SZ, LcdLightDimTask);
 os.CreateTask(TEMP_TASK, TEMP_PRIORITY, TEMP_STACK_SZ, TempTask);
+os.CreateTask(WDT_TASK, WDT_PRIORITY, WDT_STACK_SZ, WdtTask);
 
 os.CreateResource(GPS_SERIAL,GPS_SERIAL_PRIO);  
 os.CreateResource(PC_SERIAL,PC_SERIAL_PRIO);  
@@ -54,7 +55,9 @@
 os.CreateTimer(SHOW_PC_TMR, SHOW_PC_TASK, SHOW_PC_EVT);
 os.CreateTimer(LCD_LIGHT_DIM_OFF_TMR, LCD_LIGHT_DIM_TASK, LCD_LIGHT_DIM_OFF_EVT);
 os.CreateTimer(TEMP_TMR, TEMP_TASK, TEMP_EVT);
+os.CreateTimer(WDT_TMR, WDT_TASK, WDT_EVT);
 
 os.SetTimer(LCD_LIGHT_DIM_OFF_TMR, LCD_LIGHT_DIM_TIMER, 0);
+
 // os.SetTimer(TEMP_TMR, TEMP_TIMER, TEMP_TIMER); // enabled just for test or debug
 }
--- a/Startup.h	Sun Jan 29 22:08:35 2012 +0000
+++ b/Startup.h	Tue Jan 31 00:22:58 2012 +0000
@@ -1,3 +1,4 @@
+#include "mbed.h"
 #include "Common.h"
 #include "TextLCD.h"
 #include "nmea/nmea.h"
@@ -8,6 +9,7 @@
 extern mbos os;
 extern Serial pc;
 extern Serial gps;
+
 extern nmeaINFO info;
 extern nmeaPARSER parser;
 extern PwmOut LcdBklight;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task1Gps.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,147 @@
+#include "Task1Gps.h"
+
+void GpsSerialTask(void) 
+{/**
+ *\brief TASK 1, wait for the event then get the input char
+ */
+ while(1)
+ {
+    os.WaitEvent(GPS_SERIAL_IN_EVT);
+    GpsStringParse();
+            
+    Dest.lat= 4151.32496; // ***************debug
+    Dest.lon= 1229.34; // *************debug
+
+    GpsDist();
+ }
+}
+
+void GpsSerialIsr(void) 
+{/**
+ *\brief Interrupt handler for serial Rx
+         set the event for the serial task
+ */
+    char c = gps.getc();
+    msgBuff[bufferSelect & 1][writePointer] = c;
+    if (writePointer++ == BUFF_SIZE)
+    {
+        writePointer = 0;
+    }
+    if (writePointer > 200) 
+    {// GPS input buffer full, start computing coordinates
+        os.SetEvent(GPS_SERIAL_IN_EVT, GPS_SERIAL_TASK);
+    }
+}
+
+void trace_h(const char *str, int str_size) 
+{/**
+ *\brief output on console what's received on GPS serial
+          Callback function for NMEA parser buffer trace
+ */
+    if( PcMonitor==5 || PcMonitor>5)
+    {
+        for (int i = 0; i < str_size; i++)
+        {
+            pc.putc(*str++);
+        }        
+    }
+}
+
+void error_h(const char *str, int str_size) 
+{/**
+ *\brief Callback function for NMEA parser error
+ */
+    for (int i = 0; i < str_size; i++)
+    {
+        pc.putc(*str++);
+    }    
+}
+
+
+double trunc(double v) 
+{/**
+ *\brief Return nearest integer vaule less than input
+ *
+ *\parameters double variable to get nearest ingeger
+ *
+ *\return double 
+ */
+    if(v < 0.0) 
+    {
+        v*= -1.0;
+        v = floor(v);
+        v*=-1.0;
+    } else {
+        v = floor(v);
+    }
+    return v;
+}
+
+void GpsStringParse(void)
+{/**
+ *\brief parse the GPS string to extract info
+ */
+    gps.attach(NULL);   // Suspend serial interrupt while buffer change
+    size = writePointer;
+    writePointer = 0;
+    bufferSelect++;     // Change buffer
+    gps.attach( &GpsSerialIsr );  // Resume serial interrupt
+    nmea_parse(&parser, msgBuff[(bufferSelect-1)&1], size, &info);
+    Coordinates(); // transform nmea coordinates in decimal degrees
+}
+
+void GpsDist(void)
+{/**
+ *\brief compute the distance and direction (forward and reverse) 
+    from point A to point B on the ellipsoid
+ */
+  
+    nmea_info2pos(&info, &Pos[0]);  // current position  
+    nmea_info2pos(&Dest, &Pos[1]);  // destination 
+
+    Path.Dist = nmea_distance_ellipsoid(&Pos[0], &Pos[1], &Path.Azimuth[1], &Path.Azimuth[0]);
+
+    if(Path.Azimuth[0] > NMEA_PI) 
+    {// reverse direction
+        Path.Azimuth[0] = Path.Azimuth[0] - NMEA_PI; 
+    }
+    else
+    {
+        Path.Azimuth[1] = Path.Azimuth[1] + NMEA_PI; 
+    }
+
+    for(int i=0; i < 2; i++)
+    {
+        Path.Azimuth[i]=(nmea_radian2degree(Path.Azimuth[i]));
+        if(Path.Azimuth[i] > 360)
+        {
+            Path.Azimuth[i] = Path.Azimuth[i] - 360;
+        }
+        if(Path.Azimuth[i] < 0)
+        {
+            Path.Azimuth[i] = Path.Azimuth[i] + 360;
+        }
+    }
+}
+
+void Coordinates(void)
+{/**
+ *\brief transform nmea coordinates in decimal degrees
+ */
+    degrees = trunc(info.lat / 100.0);
+    minutes = info.lat - (degrees * 100.0);
+    latitude = degrees + minutes / 60.0;
+    degrees = trunc(info.lon / 100.0);
+    minutes = info.lon - (degrees * 100.0);
+    longitude = degrees + minutes / 60.0;
+ }
+  
+void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec)
+{/**
+ *\brief convert decimalDeg to Deg Min decimalSec
+ */
+    DecSec->Deg = trunc(DecDeg);
+    double MinDec = (DecDeg - DecSec->Deg);
+    DecSec->Min = trunc(MinDec * 60);
+    DecSec->Sec = (MinDec * 3600) - (DecSec->Min * 60);
+ }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task1Gps.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,39 @@
+#include "mbed.h"
+#include "Common.h"
+#include "nmea/nmea.h"
+#include "mbos.h"
+#include "Tasks.h"
+
+Serial gps(NC, GPSRX);
+
+//GPS prototypes
+void GpsStringParse(void);
+void GpsDist(void);
+void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec);
+void GpsDist(void);
+void Coordinates(void);
+void GpsSerialIsr(void);
+void trace_h(const char *str, int str_size);
+void error_h(const char *str, int str_size);
+double trunc(double v);
+
+extern mbos os;
+extern int PcMonitor;
+extern Serial pc;
+
+nmeaINFO info;                  // Store GPS information 
+nmeaPARSER parser;
+  
+DistAzimuth Path;
+nmeaPOS Pos[2];
+nmeaINFO Dest;
+
+char msgBuff[2][BUFF_SIZE];     // Receive data buffer from GPS module
+                                // Two buffer for double buffering
+                                
+volatile int writePointer = 0;  // Write pointer for active data buffer
+volatile unsigned int bufferSelect = 0; // Active buffer selector
+
+int size;
+double latitude, longitude;
+double degrees, minutes;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task2Keypad.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,105 @@
+#include "Task2Keypad.h"
+
+void KeypadTask(void)
+{/**
+ *\brief TASK 2, Keypad management. 
+         It uses just one ADC port. Five keys switch a 5 resistor ladder
+         obtaining a unique voltage for each key, with a priority that 
+         depends from the position of the resistor in the ladder.
+         This function makes an average of 50 analog values (50ms) before 
+         confirming the output, to filter out some noise and debounce keys
+ */
+
+    static float KeypadAcc;         // accumulator to compute average
+    static float KeypadPrev;        // previous value to compute variation 
+    static int KeypadCount;         // all samples number
+    static int KeypadRealCount;     // valid samples only
+    float KeypadVal;  
+    static char KeyPrev='-';
+    
+    os.SetTimer(KEYPAD_TMR, 1, 1);
+    while(1)
+    {
+        os.WaitEvent(KEYPAD_EVT);
+        float InValue = KeypadIn.read();
+        if ((InValue > 0.3) && (abs(InValue - KeypadPrev) < 0.1))
+        {// makes the average only of the values above a threshold 
+         // and within an almost stable range
+            KeypadAcc+=InValue;
+            KeypadRealCount++;
+        }
+            
+        KeypadCount++;
+        KeypadPrev=InValue;
+    
+        if (KeypadCount >=50)
+        {
+            if(KeypadRealCount > 25)
+            {
+                KeypadVal=KeypadAcc/KeypadRealCount;
+            }
+            else
+            {// not enough values to average
+    
+                KeypadVal=0;
+            }
+           
+            KeypadAcc=0;
+            KeypadCount=0;
+            KeypadRealCount=0;
+         
+            if(KeypadVal <0.15)
+            {
+                Key='-';
+            }
+            else if(KeypadVal>=0.3 && KeypadVal<0.35)
+            {
+                Key='E';
+            }
+            else if(KeypadVal>=0.42 && KeypadVal<0.50)
+            {
+                Key='v';
+            }
+            else if(KeypadVal>=0.60 && KeypadVal<0.65)
+            {
+                Key='^';
+            }
+            else if(KeypadVal>=0.74 && KeypadVal<0.78)
+            {
+                Key='>';
+            }        
+            else if(KeypadVal>=0.85)
+            {
+                Key='<';
+            }
+            
+            if (Key!='-' && Key!=KeyPrev)
+            {// switch on the LCD backlight if key pressed
+                os.SetEvent(LCD_LIGHT_DIM_ON_EVT, LCD_LIGHT_DIM_TASK);
+            }
+            KeyPrev=Key;
+            switch (Key)
+            {
+                case '^':
+                    Menu=0;
+                break;
+     
+                case '>':
+                    Menu=1;
+                break;           
+     
+                case 'v':
+                    Menu=2;
+                break;
+                
+                case '<':
+                    Menu=3;
+                break;
+                
+                case 'E':
+                    Menu=4;
+                break;
+            }     
+       }
+   } 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task2Keypad.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,10 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+
+extern mbos os;
+
+AnalogIn KeypadIn(p20);
+char Key='-';
+int Menu = 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task3Lcd.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,357 @@
+#include "Task3Lcd.h"
+
+void ShowLcdTask(void)
+{/**
+ *\brief TASK 3, display desired data on LCD
+ */
+ 
+ static int Previous=0;
+
+ os.SetTimer(SHOW_LCD_TMR, SHOW_LCD_TIMER, 0);
+ while(1)
+ {
+ os.WaitEvent(SHOW_LCD_EVT);
+
+    if(Previous != Menu)
+    {// clear the display when function changes
+        lcd.cls();
+        Previous=Menu;
+    }
+    
+    switch(Menu)
+    {
+        case 0:
+            showSatLcd();
+            Previous=0;
+            break;
+            
+        case 1:
+            if(info.sig != 0)
+            {
+                showInfoLcd();
+            }
+            else
+            {
+                showSatLcd();
+            }
+            Previous=1;    
+            break;
+        
+        case 2:
+            showMenuLcd();
+            Previous=2;    
+            break;
+            
+        case 3:
+            showMenuLcd1();
+            Previous=3;    
+            break;  
+            
+        case 4: 
+            ShowPathLcd();
+            Previous=4;    
+            break; 
+            
+        default:
+            showInfoLcd();
+            break;
+    }
+    //restart timer for other options
+    os.SetTimer(SHOW_LCD_TMR, SHOW_LCD_TIMER, 0); 
+ }
+}
+
+void ShowPathLcd(void)
+{
+    static int ChooseDir=0;
+    DegMinSec DecCoord;
+
+    Ang[Gps]=info.direction;
+    Ang[Mag]=CmpRead()-info.declination; //Compass reading corrected by declination
+    Ang[Dir]=Path.Azimuth[0];
+
+    ChooseDir++;
+    if(ChooseDir<7)
+    {
+        showDirLcd(Mag);
+    }
+    else if(ChooseDir>=7 && ChooseDir<12)
+    {
+        showDirLcd(Gps);
+    }
+    else if(ChooseDir>=12)
+    {
+       ChooseDir=0;
+    }
+    showDirLcd(Dir);
+    
+    Deg2DegMinSec(nmea_ndeg2degree(Dest.lat), &DecCoord);
+    lcd.locate(6,0);
+    lcd.printf("%d%d\'%.0f", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
+    lcd.printf("%c", Dest.lat >= 0 ? 'N': 'S');  
+    
+    Deg2DegMinSec(nmea_ndeg2degree(Dest.lon), &DecCoord);
+    lcd.locate(6,1);
+    lcd.printf("%d%d\'%.0f", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
+    lcd.printf("%c", Dest.lon >= 0 ? 'E': 'W');  
+    
+    lcd.locate(6,2);
+    lcd.printf(" dist m");
+    lcd.locate(6,3);
+    lcd.printf("%4.3f",Path.Dist);
+    
+
+}
+
+void showDirLcd(int Indx)
+{/**
+ *\brief  display a sort of compass on LCD
+ */
+    int Angle;
+
+    Angle=Ang[Indx]/18;
+
+    lcd.locate(CmpPos[Indx],0);
+    lcd.printf("  %c  ",0xA5);
+    lcd.locate(CmpPos[Indx],1);
+    lcd.printf("%c   %c",0xA5, 0xA5);
+    lcd.locate(CmpPos[Indx],2);
+    lcd.printf("%c   %c",0xA5, 0xA5);
+    lcd.locate(CmpPos[Indx],3);
+    lcd.printf("  %c  ",0xA5);
+    
+    lcd.locate(CmpPos[Indx]+1,1);
+    lcd.printf(Lab[Indx]);
+    lcd.locate(CmpPos[Indx]+1,2);
+    lcd.printf("%03i",Ang[Indx]);
+        
+    switch (Angle)
+    {
+        case 0:
+            lcd.locate(CmpPos[Indx]+2,0);
+            lcd.printf("%c",0xFF);
+            break;
+        case 1:
+            lcd.locate(CmpPos[Indx]+2,0);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+3,0);
+            lcd.printf("%c",0xFF);
+            break;
+        case 2:
+            lcd.locate(CmpPos[Indx]+3,0);
+            lcd.printf("%c",0xFF);
+            break;        
+        case 3:
+            lcd.locate(CmpPos[Indx]+3,0);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+4,1);
+            lcd.printf("%c",0xFF);
+            break;        
+        case 4:
+            lcd.locate(CmpPos[Indx]+4,1);
+            lcd.printf("%c",0xFF);
+            break;
+        case 5:       
+            lcd.locate(CmpPos[Indx]+4,1);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+4,2);
+            lcd.printf("%c",0xFF);
+            break;
+        case 6:   
+            lcd.locate(CmpPos[Indx]+4,2);
+            lcd.printf("%c",0xFF);
+            break;
+        case 7:       
+            lcd.locate(CmpPos[Indx]+4,2);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+3,3);
+            lcd.printf("%c",0xFF);
+            break;
+        case 8:   
+            lcd.locate(CmpPos[Indx]+3,3);
+            lcd.printf("%c",0xFF);
+            break;
+        case 9:       
+            lcd.locate(CmpPos[Indx]+3,3);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+2,3);
+            lcd.printf("%c",0xFF);
+            break;
+        case 10:   
+            lcd.locate(CmpPos[Indx]+2,3);
+            lcd.printf("%c",0xFF);
+            break;     
+        case 11:       
+            lcd.locate(CmpPos[Indx]+2,3);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+1,3);
+            lcd.printf("%c",0xFF);
+            break;
+        case 12:   
+            lcd.locate(CmpPos[Indx]+1,3);
+            lcd.printf("%c",0xFF);
+            break;     
+        case 13:       
+            lcd.locate(CmpPos[Indx]+1,3);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+0,2);
+            lcd.printf("%c",0xFF);
+            break;
+        case 14:   
+            lcd.locate(CmpPos[Indx]+0,2);
+            lcd.printf("%c",0xFF);
+            break;  
+        case 15:       
+            lcd.locate(CmpPos[Indx]+0,2);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+0,1);
+            lcd.printf("%c",0xFF);
+            break;
+        case 16:   
+            lcd.locate(CmpPos[Indx]+0,1);
+            lcd.printf("%c",0xFF);
+            break;  
+        case 17:       
+            lcd.locate(CmpPos[Indx]+0,1);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+1,0);
+            lcd.printf("%c",0xFF);
+            break;   
+        case 18:   
+            lcd.locate(CmpPos[Indx]+1,0);
+            lcd.printf("%c",0xFF);
+            break;  
+        case 19:       
+            lcd.locate(CmpPos[Indx]+1,0);
+            lcd.printf("%c",0xFF);
+            lcd.locate(CmpPos[Indx]+2,0);
+            lcd.printf("%c",0xFF);
+            break;   
+    }
+}
+
+void showMenuLcd(void)
+{/**
+ *\brief  display a selection menu on LCD
+ */
+    lcd.locate(0,0);
+    lcd.printf("1 - item 1");
+    lcd.locate(0,1);
+    lcd.printf("2 - item 2");
+    lcd.locate(0,2);
+    lcd.printf("3 - item 3");
+    lcd.locate(0,3);
+    lcd.printf("4 - item 4");    
+}
+
+void showMenuLcd1(void)
+{/**
+ *\brief  display a selection menu on LCD
+ */
+    lcd.locate(0,0);
+    lcd.printf("5 - item 5");
+    lcd.locate(0,1);
+    lcd.printf("6 - item 6");
+    lcd.locate(0,2);
+    lcd.printf("7 - item 7");
+    lcd.locate(0,3);
+    lcd.printf("8 - item 8");    
+}
+
+void showSatLcd(void) 
+{/**
+ *\brief displays satellite informations
+ */
+    for (int i = 0; i < NMEA_MAXSAT; i++) 
+    {
+        if(info.satinfo.sat[i].id < 20)
+        {
+            lcd.locate((info.satinfo.sat[i].id % 20) - 1,0);
+        }
+        else
+        {
+            lcd.locate((info.satinfo.sat[i].id % 20) - 1,1);    
+        }
+        
+        if (info.satinfo.sat[i].sig > 0)
+        {
+            lcd.printf("%d",info.satinfo.sat[i].sig/10);
+        }
+        else
+        {
+            lcd.printf(" ");    
+        }                   
+    }
+    lcd.locate(0,2);
+    lcd.printf("12345678901234567890");
+    lcd.locate(0, 3);
+    lcd.printf("P%2.1f H%2.1f V%2.1f %iD",
+    info.PDOP, info.HDOP, info.VDOP,info.fix);
+}    
+    
+void showInfoLcd(void) 
+{/**
+ *\brief Show nmea info on LCD 
+ */
+
+//    static int lastSat = 0;
+//    int satInview = 0;
+
+ if(info.sig != 0)
+ { 
+    lcd.locate(0, 0);
+    lcd.printf("%2.5f%c %3.5f%c",
+            latitude, info.lat >= 0 ? 'N': 'S',  
+            longitude, info.lon >= 0 ? 'E': 'W');
+  
+    lcd.locate(0, 1);
+    lcd.printf("H%.0f D%.0f_%.1f %iD", info.elv, info.direction, info.declination, info.fix);
+
+    lcd.locate(0, 2);
+    lcd.printf("P%2.1f H%2.1f V%2.1f S%i/%i",
+        info.PDOP, info.HDOP, info.VDOP, info.satinfo.inuse, info.satinfo.inview);
+        
+   /* lcd.locate(0, 3);
+    lcd.printf("%02d-%02d-%04d %02d:%02d:%02d ", 
+        info.utc.day, info.utc.mon + 1, info.utc.year + 1900,
+        info.utc.hour, info.utc.min, info.utc.sec); // Display JST (UTC + 9)
+   */
+
+/*
+    lcd.locate(0, 5);
+    for (int i = 0; i < NMEA_MAXSAT; i++) {
+        if (info.satinfo.sat[i].sig > 0) {
+            satInview++;
+            lcd.printf("  sat_id:%02d, sig:%02d, Inuse:%d \n",
+                      info.satinfo.sat[i].id , info.satinfo.sat[i].sig,
+                      info.satinfo.sat[i].in_use);
+        }
+    }
+    for (int j = satInview; j <= lastSat; j++)
+        lcd.printf("                             \n");     // delete line
+    lastSat = satInview;
+ */
+ 
+ } 
+ else
+ {
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("NO FIX"); 
+ }
+
+ // Grab a snapshot of the current RTC time.
+ time_t seconds = time(NULL);
+ char buffer[32];
+ if((info.sig != 0)&&(SetTimeOk!=0))  
+ {
+    strftime(buffer, 32, "%x %X", localtime(&seconds));
+ }
+ else
+ {// if GPS time not valid doesn't display seconds
+     strftime(buffer, 32, "%x %H:%M", localtime(&seconds));
+     SetTimeOk = 0; // RTC was not set to a valid time 
+ }
+ lcd.locate(0,3);
+ lcd.printf("%s", buffer);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task3Lcd.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,35 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+#include "TextLCD.h"
+#include "nmea/nmea.h"
+
+// LCD prototypes
+void ShowPathLcd(void);
+int CmpRead(void);
+void TempTask(void);
+void LcdLightDimTask(void);
+void showDirLcd(int Indx);
+void showMenuLcd1(void);
+void showMenuLcd(void);
+void showSatLcd(void);void showDirLcd(int Indx);
+void showMenuLcd1(void);
+void showMenuLcd(void);
+void showSatLcd(void);
+void showInfoLcd(void);
+void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec);
+
+extern mbos os;
+extern nmeaINFO info;
+extern DistAzimuth Path;
+extern nmeaINFO Dest;
+extern double latitude, longitude;
+extern int Menu;
+extern int SetTimeOk;
+
+TextLCD lcd(p12, p11, p24, p23, p22, p21, TextLCD::LCD20x4); // rs, e, d4-d7
+
+const char *Lab[]={"MAG", "DIR", "GPS"}; //Label to display in compass view
+int CmpPos[]={0,15,0}; //Compass position
+int Ang[3]; //Compass angle values
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task4LedBlink.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,101 @@
+#include "Task4LedBlink.h"
+
+void LedBlinkTask(void)
+{/**
+ *\brief TASK 4
+         LED 1: Quick blink=NOT fix, Slow blink=fix OK  
+         LED 2: blinks proportionally to HDOP
+         LED 3: blinks proportionally to VDOP
+ */
+
+ static int LedCnt1=0;
+ //    static int LedCnt2=0;
+ int OnH=0;
+ int OnV=0;
+
+ #define MAX 20
+  
+ os.SetTimer(LED_BLINK_TMR, 100, 100);
+
+ while(1)
+ {
+    os.WaitEvent(LED_BLINK_EVT);
+            
+    if((info.HDOP>0)&&(info.HDOP<=2))
+    {
+        OnH=2;
+    }
+    else if((info.HDOP>2)&&(info.HDOP<=4))
+    {
+        OnH=4;    
+    }
+    else if((info.HDOP>4)&&(info.HDOP<=6))
+    {
+        OnH=6;    
+    }
+    else if((info.HDOP>6))
+    {
+        OnH=MAX/2;    
+    }        
+
+    if((info.VDOP>0)&&(info.VDOP<=2))
+    {
+        OnV=2;
+    }
+    else if((info.VDOP>2)&&(info.VDOP<=4))
+    {
+        OnV=4;    
+    }
+    else if((info.VDOP>4)&&(info.VDOP<=6))
+    {
+        OnV=6;    
+    }
+    else if((info.VDOP>6))
+    {
+        OnV=MAX/2;    
+    } 
+           
+    if(info.sig == 0)
+    {
+        led1=!led1;
+        led2=0;
+        led3=0;
+    }
+    else
+    {
+       if(LedCnt1<=MAX/2)
+       {
+            LedCnt1++;
+            led1=0;
+            if(LedCnt1<OnH)
+            {
+               led2=!led2; 
+            }
+            else 
+            {
+                led2=0;
+            }    
+            
+            if(LedCnt1<OnV)
+            {
+               led3=!led3; 
+            }
+            else 
+            {
+                led3=0;
+            }          
+       } 
+       else if((LedCnt1>MAX/2)&&(LedCnt1<=MAX))
+       {
+            LedCnt1++;
+            led1=1;
+            led2=0;
+            led3=0;
+       }
+       else if(LedCnt1>MAX)
+       {
+            LedCnt1=0;       
+       }
+    }
+ }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task4LedBlink.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,13 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+#include "nmea/nmea.h"
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+extern mbos os;
+extern nmeaINFO info;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task5SetTime.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,29 @@
+#include "Task5SetTime.h"
+
+void SetTimeTask(void)
+{/**
+ *\brief TASK 5, Set RTC system time if the GPS time is valid
+ */
+ struct tm t;
+ 
+ os.SetTimer(SET_TIME_TMR, 60000, 60000);
+ while(1)
+ {  
+ os.WaitEvent(SET_TIME_EVT);
+
+    if(info.sig != 0)    
+    {
+       t.tm_mday=info.utc.day;
+       t.tm_mon=info.utc.mon;
+       t.tm_year=info.utc.year; 
+       t.tm_hour=info.utc.hour;
+       t.tm_min=info.utc.min;
+       t.tm_sec=info.utc.sec;        
+          
+        time_t seconds = mktime(&t);       
+        set_time(seconds);
+        
+        SetTimeOk = 1; // RTC was set 
+    }
+ }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task5SetTime.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,9 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+#include "nmea/nmea.h"
+
+extern mbos os;
+extern nmeaINFO info;
+int SetTimeOk=0; // is RTC in sync?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task6Pc.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,50 @@
+#include "Task6Pc.h"
+
+void ShowPcTask(void) 
+{/**
+ *\brief TASK 6, if a PC is connected, debug information can be sent to the console
+ */
+ static int it = 0;
+ int i;
+ DegMinSec DecCoord;
+    
+ os.SetTimer(SHOW_PC_TMR, 1000, 1000);
+ while(1)
+ {
+    os.WaitEvent(SHOW_PC_EVT); 
+
+    if(pc.readable())
+    {// wait for an input
+        PcMonitor = (pc.getc()-48); // digit a number to en/dis-able debug
+     }
+     
+    if( PcMonitor==1 || PcMonitor>5)
+    {// Display Info parameters 
+        pc.printf(
+        "%03d, Lat: %f, Lon: %f, Sig:%d, Fix:%d, Inuse:%d\r\n",
+        it++, latitude, longitude, info.sig, info.fix, info.satinfo.inuse );
+        for (i = 0; i < NMEA_MAXSAT; i++) 
+            {
+            if (info.satinfo.sat[i].sig > 0)
+            pc.printf("  sat_id:%02d, sig:%02d, Inuse:%d\r\n",
+                      info.satinfo.sat[i].id , info.satinfo.sat[i].sig, 
+                      info.satinfo.sat[i].in_use);
+            }
+        pc.printf("\r\n");
+    }
+    
+    if( PcMonitor==2 || PcMonitor>5)
+    {// Display Distance parameters 
+        Deg2DegMinSec(nmea_radian2degree(Pos[0].lat), &DecCoord);
+        pc.printf("Lat1:%d %d\'%.3f\"  ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
+        Deg2DegMinSec(nmea_radian2degree(Pos[0].lon), &DecCoord);
+        pc.printf("Lon1:%d %d\'%.3f\"  ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
+        Deg2DegMinSec(nmea_radian2degree(Pos[1].lat), &DecCoord);
+        pc.printf("Lat2:%d %d\'%.3f\"  ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
+        Deg2DegMinSec(nmea_radian2degree(Pos[1].lon), &DecCoord);
+        pc.printf("Lon2:%d %d\'%.3f\"  \n", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
+        pc.printf("Dist:%f  Azimuth Start:%f  Azimuth Final:%f \n\n",
+                  Path.Dist, Path.Azimuth[0], Path.Azimuth[1]); 
+    }
+  }   
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task6Pc.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,18 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+#include "nmea/nmea.h"
+
+void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec);
+
+extern mbos os;
+extern nmeaINFO info;
+extern int SetTimeOk;
+extern double latitude, longitude;
+extern nmeaPOS Pos[];
+extern DistAzimuth Path;
+
+int PcMonitor=0;    // to control serial out on USB serial
+
+Serial pc(USBTX, USBRX);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task7Dim.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,36 @@
+#include "Task7Dim.h"
+
+void LcdLightDimTask(void)
+{/** 
+ *\brief TASK 7, control the LCD backlight intensity to smoothly
+         switch it on or off
+ */
+ static float LightVal=1;
+        
+ while(1)
+ {       
+    os.WaitEvent(LCD_LIGHT_DIM_ON_EVT | LCD_LIGHT_DIM_OFF_EVT); 
+    if(os.GetEvent()==LCD_LIGHT_DIM_ON_EVT)
+    {
+      if(LightVal<1)
+      {
+        for (LightVal=0; LightVal<=1; LightVal+=0.01f)
+        {
+            LcdBklight=LightVal;
+            wait_ms(10);
+        }
+      }
+    // Set the timer for the power saving backlight switch off
+    os.ClearTimer(LCD_LIGHT_DIM_OFF_TMR);
+    os.SetTimer(LCD_LIGHT_DIM_OFF_TMR, LCD_LIGHT_DIM_TIMER, 0);
+    }
+    else if(os.GetEvent()==LCD_LIGHT_DIM_OFF_EVT)
+    {// The dimming off is slower than lighting up
+        for (LightVal=1; LightVal>=0; LightVal-=0.01f)
+        {
+            LcdBklight=LightVal;           
+            wait_ms(30);
+        }        
+    }
+ }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task7Dim.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,9 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+
+extern mbos os;
+
+// Ports initialization
+PwmOut LcdBklight(p25);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task8Temp.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,21 @@
+#include "Task8Temp.h"
+
+void TempTask(void)
+{/**
+ *\brief TASK 8 used to temporary test some functions 
+ */
+ static int TempAng;
+ while (1)
+ {
+  os.WaitEvent(TEMP_EVT); 
+  
+  if((TempAng+=5) >=360)
+  {
+    TempAng=0;
+  }
+  Ang[Mag]=TempAng;
+  Ang[Dir]=360-TempAng;
+  Ang[Gps]=180-TempAng;
+  printf("%i %i  %i \n", Ang[0], Ang[1], Ang[2]);
+ }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task8Temp.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,8 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+
+extern mbos os;
+
+extern int Ang[];
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task9Wdt.cpp	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,18 @@
+#include "Task9Wdt.h"
+
+void WdtTask(void)
+{/**
+ *\brief TASK 9 Watch Dog 
+        this is a very high priority task. Non other task can
+        block this one. So, the WDT occurs only if a real OS
+        hang happens.
+ */
+ 
+ os.SetTimer(WDT_TMR, WDT_TIMER, WDT_TIMER); // Kick the dog
+
+ while (1)
+ {
+    os.WaitEvent(WDT_EVT);     
+    wd.Service();       // kick the dog before the timeout
+ }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Task9Wdt.h	Tue Jan 31 00:22:58 2012 +0000
@@ -0,0 +1,9 @@
+#include "mbed.h"
+#include "Common.h"
+#include "mbos.h"
+#include "Tasks.h"
+#include <Watchdog.h>
+
+extern mbos os;
+
+Watchdog wd;
--- a/Tasks.h	Sun Jan 29 22:08:35 2012 +0000
+++ b/Tasks.h	Tue Jan 31 00:22:58 2012 +0000
@@ -48,7 +48,14 @@
 #define TEMP_STACK_SZ               32
 void TempTask(void);  
 
-#define NUM_TASKS                    8
+// Task 9 - Kick the WDT dog
+#define WDT_TASK                     9
+#define WDT_PRIORITY                90
+#define WDT_STACK_SZ               128
+void WdtTask(void);  
+
+
+#define NUM_TASKS                    9
 
 // timers ------------------------------
 #define KEYPAD_TMR                   0
@@ -58,8 +65,9 @@
 #define SHOW_PC_TMR                  4
 #define LCD_LIGHT_DIM_OFF_TMR        5
 #define TEMP_TMR                     6
+#define WDT_TMR                      7
 
-#define NUM_TIMERS                   7
+#define NUM_TIMERS                   8
 
 // resources ---------------------------
 #define PC_SERIAL                    0
@@ -86,4 +94,5 @@
 #define LCD_LIGHT_DIM_ON_EVT  0x00000040
 #define LCD_LIGHT_DIM_OFF_EVT 0x00000080
 #define TEMP_EVT              0x00000100
+#define WDT_EVT               0x00000200