/*******************************************************************************
* @file    Timer2.cpp
* @brief
* @version V0.0.1
* @date    01/12/2012
*
* THE SOURCE CODE AND ITS RELATED DOCUMENTATION IS PROVIDED "AS IS". KRONEGGER
* GMBH MAKES NO OTHER WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED OR,
* STATUTORY AND DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
* SATISFACTORY QUALITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
*
* THE SOURCE CODE AND DOCUMENTATION MAY INCLUDE ERRORS. KRONEGGER GMBH
* RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE SOURCE CODE IN LATER
* REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE DOCUMENTATION OR
* THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.
*
* KRONEGGER GMBH SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL
* DAMAGE OR LIABILITY ARISING FROM YOUR USE OF THE SOURCE CODE OR ANY
* DOCUMENTATION, INCLUDING BUT NOT LIMITED TO, LOST REVENUES, DATA OR PROFITS,
* DAMAGES OF ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL NATURE, PUNITIVE DAMAGES,
* LOSS OF PROPERTY OR LOSS OF PROFITS ARISING OUT OF OR IN CONNECTION WITH THIS
* AGREEMENT, OR BEING UNUSABLE, EVEN IF ADVISED OF THE POSSIBILITY OR
* PROBABILITY OF SUCH DAMAGES AND WHETHER A CLAIM FOR SUCH DAMAGE IS BASED UPON
* WARRANTY, CONTRACT, TORT, NEGLIGENCE OR OTHERWISE.
*
* (C)Copyright Kronegger GmbH 2012 All rights reserved
******************************************************************************/

#include "API.h"
#include "hardware.h"
#include "MSP430_hardware.h"

/**
*Start Timer
*
*starts a time with a value which is set as parameter
*
*@param msec contains the length of the timer
*/

Timer::Timer()  { running=false; t=0;}

inline dword getTicks32()
{
    return HWTimer::ticks32();

}

void Timer::Start(dword msec)
{
	t=(long)getTicks32(); 
        running=true;
	t+=msec*HWTimer::TICKS_PER_MSEC;
}

/**
*Restart Timer
*
*restarts the timer with a defined time
*
*@param msec contains the length of the restarttime
*/
void Timer::ReStart(dword msec)
{
	t+=msec*HWTimer::TICKS_PER_MSEC;
	running=true;
}
/**
*Stop Timer
*
*stops the timer
*
*/
void Timer::Stop()
{
  t=0;
  running=false;
}
/**
*@return returns the value of the timer
*/
dword Timer::GetTime()
{
	if(!running) return 0;
	
	long temp=(t-(long)getTicks32());
	
	if(temp>0)
	{
		return (word)(temp/HWTimer::TICKS_PER_MSEC);
	}
	return 0;
}

/**
*is Elapsed?
*
*to check wether the timer is elapsed or not.
*
*@return return true iff the timer is elapsed and returns false if the timer is running
*/
bool Timer::iselapsed()
{
	if(!running) return true;  //timer has elapsed before
	long tmp=(long)getTicks32()-t;
	if(tmp > 0) // is elapsed ?
	{
		running=false; //mark as elapsed
		return true;
	}
	return false;
}

bool Timer::isactive()
{
  if(t==0)
    return false;
  else
    return true;
}

/**
*Messure Time
*
*starts a stopwatch to meassure the timing
*/
void Timer::tic()
{
  t=getTicks32()/HWTimer::TICKS_PER_MSEC;
}
/**
*Messure Time
*
*get a time of the stopwatch
*/
double Timer::toc()
{
  if(t==0)
    return 0;
  double temp;
  temp=(getTicks32()/HWTimer::TICKS_PER_MSEC)-t;
  return temp;
}

dword Timer::GetTicks32(){
    return getTicks32();
}

/**
*WaitMs
*
*wait a defined time to go on with the code.Avoid to use it. This is a blocking function
*@param ms contains the time length of the blocking wait
*/
void waitms(word ms)
{
    Timer t;
   // if(ms == 0) {HWTimer::ticks32(); return; } //used to do timmer housekeeping without delay
    t.Start(ms);
    while(!t.iselapsed()) HW::Idle(); //blocking wait -- avoid to use it !
    //while(!t.iselapsed());
}
/**
*Waitus
*
*wait a defined time to go on with the code.Avoid to use it. This is a blocking function
*@param ms contains the time length of the blocking wait
*/
void waitus(word usec)
{
    long t;
    t=(long)HWTimer::ticks32();
    t+=(usec*HWTimer::TICKS_PER_MSEC)/1000;
    while(1)
    {
        long tmp=(long)getTicks32()-t;
        if(tmp > 0) return;// is elapsed ?
        //HW::Idle();
    }
}
