
#include "nrf_gpio.h"
#include "Common.h"

unsigned char	Timer1_Tick = 0;

/* 變數定義 -----------------------------------------------*/
int		gStepCnt = 0;
//（P0.2-P0.5）各位分別取1，二進制碼即：00000100，00001000，00010000，00100000
// 正轉:
// Step		1		2		3		4
// ------------------------------------------------
// P21:		1		0		0		0
// P22:		0		1		0		0
// P23:		0		0		1		0
// P24:		0		0		0		1
/*
uchar code table1[2][4]= {
	{0x04,0x08,0x10,0x20};			// 正轉表格，
	{0x20,0x10,0x08,0x04};			// 反轉表格
};
*/
// 反轉:
// Step		1		2		3		4
// ------------------------------------------------
// P21:		0		0		0		1
// P22:		0		0		1		0
// P23:		0		1		0		0
// P24:		1		0		0		0
unsigned char	StepTable[4][4] = {			// [步數][GPIO]
	{	1,	0,	0,	0	},
	{	0,	1,	0,	0	},
	{	0,	0,	1,	0	},
	{	0,	0,	0,	1	}
};
char	Direct[4];

//保持低電位的 Tick
unsigned char	PeriodTable[MaxTickValue + 1][2] = {
			{	0,		10		},
			{	1,		9		},
			{	2,		8		},
			{	3,		7		},
			{	4,		6		},
			{	5,		5		},
			{	6,		4		},
			{	7,		3		},
			{	8,		2		},
			{	9,		1		},
			{	10,		0		}
};
				
// ----- use IRQ -----

// ----- Timer-0 -----
#define DEBOUNCE_INPUT_SAMPLING_FREQ    (1U)                                   	/**< Input sampling frequency in Hertz */
#define TIMER0_PRESCALER                (8UL)									/**< Timer 0 prescaler */
#define TIMER0_CLOCK                    (SystemCoreClock >> TIMER0_PRESCALER)	/**< Timer clock frequency */
#define MS_TO_TIMER0_TICKS(ms)          ((1000000UL * ms) / (TIMER0_CLOCK))		/**< Converts milliseconds to timer ticks */

char	TimerStatus = 0;											// 0: 比較長的時間, 非0:  比較短的時間
uint_fast16_t timer0_cc0_period;
/* @brief Interrupt handler function for the Timer 0 peripheral. */
void TIMER0_IRQHandler(void)
{
    if ((NRF_TIMER0->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER0->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
    {
        NRF_TIMER0->EVENTS_COMPARE[0] = 0;
		if ( TimerStatus )
		{
			//	nrf_gpio_pin_write(LED_Yellow, 1);
			//	NRF_TIMER0->CC[0]            += (timer0_cc0_period / 16);
			NRF_TIMER0->CC[0]            += timer0_cc0_period / 16;
		}
		else
		{
			//	nrf_gpio_pin_write(LED_Yellow, 0);
			NRF_TIMER0->CC[0]            += timer0_cc0_period;
		}
		//	nrf_gpio_port_write(LEDS, LEDStatus);
	    TimerStatus = ~TimerStatus;
    }
}

/* @brief Function for initializing Timer 0. */
void IRQtimer0_init(void)
{
	// Set the timer in Timer Mode
	NRF_TIMER0->MODE      = TIMER_MODE_MODE_Timer;
	NRF_TIMER0->PRESCALER = TIMER0_PRESCALER;

	// 24-bit mode
	NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_24Bit;

	// Enable interrupt for COMPARE[0]
	NRF_TIMER0->INTENSET    = (1UL << TIMER_INTENSET_COMPARE0_Pos);
	NRF_TIMER0->CC[0]       = timer0_cc0_period;
	NRF_TIMER0->TASKS_START = 1; // Start clocks
}

// #define DEBOUNCE_INPUT_SAMPLING_FREQ    (1U)                                   	/**< Input sampling frequency in Hertz */
#define TIMER1_PRESCALER                (9UL)									/**< Timer 1 prescaler */
#define TIMER1_CLOCK                    (SystemCoreClock >> TIMER1_PRESCALER)	/**< Timer clock frequency */
#define MS_TO_TIMER1_TICKS(ms)          ((1000000UL * ms) / (TIMER1_CLOCK))		/**< Converts milliseconds to timer ticks */

uint_fast16_t timer1_cc0_period = TIMER1_PEROID;
unsigned long	Timer1_GlobalTick = 0;
unsigned char	gDutycycleId = 0;
/* @brief Interrupt handler function for the Timer 1 peripheral. */
void TIMER1_IRQHandler(void)
{
	unsigned char	Tick_High = PeriodTable[gDutycycleId][0];
	unsigned char	Tick_Low = PeriodTable[gDutycycleId][1];
	static	unsigned char	lMotorStatus = 0;
    if ((NRF_TIMER1->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
    {
        NRF_TIMER1->EVENTS_COMPARE[0] = 0;
    #if 1
    	NRF_TIMER1->CC[0]            += (timer1_cc0_period);
    	Timer1_Tick++;
    	Timer1_GlobalTick++;
    	//	if ( Timer1_Tick == MaxTickValue )
    	//		Timer1_Tick = 0;
    	if ( gDutycycleId == 0 )
    	{
    		nrf_gpio_pin_clear(MotorControl_A);
    		nrf_gpio_pin_clear(MotorControl_B);
    		nrf_gpio_pin_clear(MotorControl_C);
    		nrf_gpio_pin_clear(MotorControl_D);
    	}
    	else if ( gDutycycleId == 10 )
    	{
    		nrf_gpio_pin_set(MotorControl_A);
    		nrf_gpio_pin_set(MotorControl_B);
    		nrf_gpio_pin_set(MotorControl_C);
    		nrf_gpio_pin_set(MotorControl_D);
    	}
    	else
    	{
    		if ( lMotorStatus )
    		{
    			if ( Timer1_Tick > Tick_High )
    			{
    				Timer1_Tick = 0;
    				lMotorStatus = 0;
    				nrf_gpio_pin_toggle(MotorControl_A);
    				nrf_gpio_pin_toggle(MotorControl_B);
    				nrf_gpio_pin_toggle(MotorControl_C);
    				nrf_gpio_pin_toggle(MotorControl_D);
    			}
    		}
    		else
    		{
     			if ( Timer1_Tick > Tick_Low )
    			{
    				Timer1_Tick = 0;
    				lMotorStatus = 1;
    				nrf_gpio_pin_toggle(MotorControl_A);
    				nrf_gpio_pin_toggle(MotorControl_B);
    				nrf_gpio_pin_toggle(MotorControl_C);
    				nrf_gpio_pin_toggle(MotorControl_D);
    			}
    		}
    	}
    #else
		if ( TimerStatus )
		{
			NRF_TIMER1->CC[0]            += (timer1_cc0_period);
		}
		else
		{
	    	NRF_TIMER1->CC[0]            += (timer1_cc0_period);
	    }
	#endif
	    TimerStatus = ~TimerStatus;
    }
}

/* @brief Function for initializing Timer 1. */
void IRQtimer1_init(void)
{
	// Set the timer in Timer Mode
	NRF_TIMER1->MODE      = TIMER_MODE_MODE_Timer;
	NRF_TIMER1->PRESCALER = 9;											// 0~9 ==> 數字愈大, 周期愈長

	// 24-bit mode
	NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_24Bit;

	// Enable interrupt for COMPARE[0]
	NRF_TIMER1->INTENSET    = (1UL << TIMER_INTENSET_COMPARE0_Pos);
	NRF_TIMER1->CC[0]       = timer1_cc0_period;
	NRF_TIMER1->TASKS_START = 1; // Start clocks
}


void InitTimerIRQ(void)
{
#if 0			// Timer 0
	// DEBOUNCE_INPUT_SAMPLING_FREQ is in hertz, Multiply by 1000 to get milliseconds
	//	timer0_cc0_period = MS_TO_TIMER0_TICKS((1000 * 1 / DEBOUNCE_INPUT_SAMPLING_FREQ));
	timer0_cc0_period = MS_TO_TIMER0_TICKS((3000 * 1 / DEBOUNCE_INPUT_SAMPLING_FREQ));	// 算出來是 0x4E3E
	IRQtimer0_init();
    NVIC_EnableIRQ(TIMER0_IRQn);
#endif
#if 1			// Timer 1
	// DEBOUNCE_INPUT_SAMPLING_FREQ is in hertz, Multiply by 1000 to get milliseconds
	//		timer1_cc0_period = MS_TO_TIMER1_TICKS((3000 * 1 / DEBOUNCE_INPUT_SAMPLING_FREQ));
	timer1_cc0_period = TIMER1_PEROID;									// 數字愈小, 周期愈短 (閃的愈快)
	IRQtimer1_init();
	NVIC_EnableIRQ(TIMER1_IRQn);
#endif
}
	
