#define __TIMER

#include "common.h"
#include <stdio.h>
#include "timer.h"
#include "tortola_memory_map_defines.h"
//#include "stddefs.h"
//#include "mx21.h"


static U32 TmrMS[NO_OF_TIMER_MS];
static U32 Cnt500us;
static int get_timer_number(int wait_period); 

void TmrMS_drv (void);

#define EGPT_DIVIDE_BY 67  //eug          // EGPT running at 52 MHz instead of 13 MHz

int get_timer_number(int wait_period) 
{
int timer_number;
        //timer_number = (int) (wait_period * EGPT_DIVIDE_BY / 2) + 1 ; // jmh: delay is half what it should be?
        timer_number = (int) (wait_period * EGPT_DIVIDE_BY) + 1 ;
        return timer_number;
}

void GPT1Init (U32 int_period_us)
{
//	*(volatile P_U32)(CRM_PCCR1) |= bit25;
	*(volatile P_U32)(CCM_CGR1) |= bit25;

	*(volatile P_U32) GPT_GPTCR	= 0x00000000;		// disable timer1
//   reg32clrbit(GPT_GPTCR,0x6);

//	*(volatile P_U32) TSTAT1 &= 0xfffffffe;		// clear any previous compare event
	*(volatile P_U32) GPT_GPTSR = 0x00000000;		// clear any previous compare event
	*(volatile P_U32) GPT_GPTPR = 0x00000000;		// Set timer prescaler

	*(volatile P_U32) GPT_GPTCR	= bit0;
	*(volatile P_U32) GPT_GPTCR	|= bit15;			// set SWR
	*(volatile P_U32) GPT_GPTCR	= 0x00000000;		// disable timer1

// TCMP1 - 1 = interrupt time x 32.768K
	
/*
	switch (int_period_us)
	{
		case 125:
			*(volatile P_U32) GPT_GPTOCR1	= 	4-1;	// 1/32.768K * 4 = 122us
			break;

		case 250:
			*(volatile P_U32) GPT_GPTOCR1	= 	8-1;	// 1/32.768K * 8 = 244us
			break;

		case 500:
			*(volatile P_U32) GPT_GPTOCR1	= 	16-1;	// 1/32.768K * 16 = 488us
			break;

		case 1000:
			*(volatile P_U32) GPT_GPTOCR1	= 	32-1;	// 1/32.768K * 32 = 977us
			break;

		case 2000:
			*(volatile P_U32) GPT_GPTOCR1	= 	64-1;	// 1/32.768K * 64 = 1953us
			break;

		default:
			printf ("\n\nIncorrect setting for GPT_GPTOCR1\n\n");
			break;
	}
*/
    *(volatile P_U32) GPT_GPTOCR1 = get_timer_number(int_period_us);

	*(volatile P_U32) GPT_GPTCR	= 	0x00000009;		// bit 4 : enable timer interrupt
														// bit 3..1 : 100 Clock source = 32KHz
														// bit 0 : enable timer
														
//reg32setbit(GPT_GPTCR,0x6);
//reg32setbit(GPT_GPTCR,0x0);
}

U32 timer1_cmp_stat (void)
{
	return (*(volatile P_U32) GPT_GPTSR & bit0);
}



void wait_ms (U32 time_ms)
{
	while (time_ms)
		if (*(volatile P_U32) GPT_GPTSR & bit0)
		{
			*(volatile P_U32) GPT_GPTSR &= ~bit0;
			time_ms--;
		}
}

void timer1_500us_chk (void)
{
	U32 i;
	
	if (*(volatile P_U32) GPT_GPTSR & bit0)
	{
		*(volatile P_U32) GPT_GPTSR &= ~bit0;

		switch ((Cnt500us++)&0x7)
		{
			case 0: case 2: case 4: case 6:		// Timer with 1ms resolution
				TmrMS_drv();
				break;

			case 1: case 5:						// 2ms time slot
				break;

			case 3:								// 4ms time slot

				break;

			case 7:								// 4ms time slot
				break;

			default:
				break;
		}
	}
}





void WaitTmrMS (U8 timer_no, U32 time)
{
	TmrMS[timer_no]=time;

	while (TmrMS[timer_no])
		timer1_500us_chk();
}




void TmrMS_drv (void)
{
	U32 i;

	for (i=0; i<NO_OF_TIMER_MS; i++)
		if (TmrMS[i])
			TmrMS[i]--;
			
}


void SetTmrMS (U8 timer_no, U32 time)
{
	TmrMS[timer_no]=time;
}


U32 GetTmrMS (U8 timer_no)
{
	return (TmrMS[timer_no]);
}
	

