/*
  MsTimer2.h - Using timer2 with 1ms resolution
  cuijan <cui.jian.510@gmail.com>

  History:
	1/Jun/24  - V1.2 released working on MG32x02z only

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <MsTimer2.h>
#include "timer.h"

/*0
namespace MsTimer2 {
	extern unsigned long msecs;
	extern void (*func)();
	extern volatile unsigned long count;
	extern volatile char overflowing;
	extern volatile unsigned int tcnt2;
	
	void set(unsigned long ms, void (*f)());
	void start();
	void stop();
	void _overflow();
}
*/

unsigned long MsTimer2::msecs;
void (*MsTimer2::func)();
volatile unsigned long MsTimer2::count;
volatile char MsTimer2::overflowing;
volatile unsigned int MsTimer2::tcnt2;
/*  
#if defined(__arm__) &&defined(MG32F02U128) 
static IntervalTimer itimer;
#endif
*/
#if defined(MG32F02U128) 
#define USED_MSTIMER2_ID  TIM20_E
#endif

#if defined (MG32F02U128) 
void MsTimer2_ISR(timer_id_e timer_id)
{
    TimerHandleSetCounter( timer_id,   MsTimer2::tcnt2,  MsTimer2::tcnt2);
	MsTimer2::_overflow();
}
#endif //#if defined (MG32F02U128) 


void MsTimer2::set(unsigned long ms, void (*f)()) 
{
	if (ms == 0)
	{
		msecs = 1;
	}
	else
	{
		msecs = ms;
	}
	func = f;
	
    TimerHandleInitByPeriod( USED_MSTIMER2_ID,  1000  );
    TimerAttachIntHandle( USED_MSTIMER2_ID, MsTimer2_ISR  );
	tcnt2 = TimerHandleGetCounter( USED_MSTIMER2_ID );
}

void MsTimer2::start() 
{
	count = 0;
	overflowing = 0;

    TimerHandleInitByPeriod( USED_MSTIMER2_ID,  1000 );
    TimerAttachIntHandle( USED_MSTIMER2_ID, MsTimer2_ISR  );
	tcnt2 = TimerHandleGetCounter( USED_MSTIMER2_ID );
	TimerHandleStart( USED_MSTIMER2_ID );
}

void MsTimer2::stop()
{
    TimerHandleStop( USED_MSTIMER2_ID );
}

void MsTimer2::_overflow()
{
	count += 1;
	
	if (count >= msecs && !overflowing) 
	{
		overflowing = 1;
		count = count - msecs;   // subtract ms to catch missed overflows
					             // set to 0 if you don't want this.

		(*func)();
		overflowing = 0;
	}
}



