/*
 * Step-Motor Driver Demo Application
 * Copyright (c) 2013-2014 China JiLiang University
 * All Rights Reserved.
 */

/*!
 * @file        main.c
 * @version     1.0
 * @author      Kai Zhang
 * @date        2013-07-21
 * @brief       Step-Motor_PWM_Tiva 4PWMźţת
 * 				PB7 PB4 PF1 PF2ΪPWMźţռձͳһΪ25%
 * 				PB7 PB4 PF1 PF2λһβ90λƫ
 * 				ֵͨPWMڣڵڷΧ25Hz~50Hz֮
 *
 */

//#ifndef TARGET_IS_BLIZZARD_RA1
//#define TARGET_IS_BLIZZARD_RA1
//#endif

#ifndef  PART_TM4C123GH6PM
#define  PART_TM4C123GH6PM
#endif
//###############################################################################################
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "LCDDriver.h"
#include "driverlib/rom.h"
#include "driverlib/PWM.h"
#include "driverlib/adc.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/rom.h"
#include "driverlib/timer.h"
//###############################################################################################
unsigned char duty;			// ռձѡ
#define MAX_ADC_VALUE	4096
extern unsigned long adcWheel_value = 0;			// ʵʱADCĹֵ
uint32_t cur_Duty, old_Duty = 0; 					// ݹADCתֵǰʱֵ
/************************************************************************
 * @brief  	ʼADCȡֵѹֵ
 * 		|
//		TIVA	|
//		M4	 PE0|<--ADC		ģתźԴ
//		________|
 *
 ***********************************************************************/
#define ADC_BASE		ADC0_BASE			// ʹADC0
#define SequenceNum 	3					// ʹ3
void Init_ADCWheel(){

	// ʹADC0
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

	// ʹ˿E
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

	// ѡPE0Ϊⲿģת
	ROM_GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);

	// ʹܲкΪȡģʽ
	ROM_ADCSequenceConfigure(ADC_BASE, SequenceNum, ADC_TRIGGER_PROCESSOR, 0);

	// ADC
	ROM_ADCSequenceStepConfigure(ADC_BASE, SequenceNum, 0, ADC_CTL_CH3 | ADC_CTL_IE |
							 ADC_CTL_END);

	// ʹADC
	ROM_ADCSequenceEnable(ADC_BASE, SequenceNum);

	// ADCжϱ־λ
	ROM_ADCIntClear(ADC_BASE, SequenceNum);
}

int count = 0;
#define A_U				GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_7, GPIO_PIN_7);
#define B_U				GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_PIN_4);
#define C_U				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
#define D_U				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

#define A_D				GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_7, GPIO_PIN_0);
#define B_D				GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_PIN_0);
#define C_D				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_0);
#define D_D				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_0);
/************************************************************************
 * @brief  	ӦʱжPWM
 *
 ***********************************************************************/
void Int_TimerW0A_Handler(void)
{

	TimerIntClear (WTIMER0_BASE, TIMER_TIMA_TIMEOUT);
	TimerEnable (WTIMER0_BASE, TIMER_A);

	count++;
	count = count % 4;

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_7);
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2);

//	cur_tick = ROM_SysTickValueGet();
//	if(old_tick > cur_tick)
//		tick_delay = old_tick - cur_tick;
//	else
//		tick_delay = (0x0FFFFFFF + old_tick) - cur_tick;
//	old_tick = cur_tick;

	switch (count)
	{
	case 0:
		A_D
		C_U
		break;
	case 1:
		C_D;
		B_U;
			break;
	case 2:
		B_D;
		D_U;
			break;
	case 3:
		D_D;
		A_U;
			break;
	}
}

/************************************************************************
 * @brief  	ʼPWMȡ鷴ź
 * 		|
//		TIVA	|
 * 		M4	 PB7|-->M0PWM1			---------Channel 1
//		M4	 PB4|-->M0PWM2			---------Channel 2
 * 		M4	 PF1|-->M1PWM5			---------Channel 3
 * 		M4	 PF2|-->M1PWM6			---------Channel 4
//		________|
 *
 ***********************************************************************/
void Init_PWM()
{
	// Enable the peripherals used by this example.
	ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_WTIMER0);

	// Enable processor interrupts.
	ROM_IntMasterEnable ();

	// Configure the two 32-bit periodic timers.
	ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_WTIMER0);

	// 8K HzӦ
	ROM_TimerLoadSet (WTIMER0_BASE, TIMER_A, ROM_SysCtlClockGet());


	// Setup the interrupts for the timer timeouts.
	ROM_IntEnable (INT_WTIMER0A);

	ROM_TimerIntEnable (WTIMER0_BASE, TIMER_TIMA_TIMEOUT);

	// Enable the timers.
	ROM_TimerEnable (WTIMER0_BASE, TIMER_A);
}

//###############################################################################################
/********************************
 * 
 * *******************************/
int main(void)
{
	uint32_t pui32ADC0Value[1];			// ADCֵ

	// ϵͳʱ
	SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
	                   SYSCTL_XTAL_16MHZ);

	// ʼ
	Init_ADCWheel();

	// ʼPWM
	Init_PWM();

	// ʹLCD
	LCD_Enable();

	// ʼLCD
	LCD_Init();

	// 
	LCD_ScreenClr();

	// ʾrpm תٵλ ת/ַ֡
//	LCD_Draw_Char('S', 0, 0);
//	LCD_Draw_Char('p', 0, 8);
//	LCD_Draw_Char('e', 0, 16);
//	LCD_Draw_Char('e', 0, 24);
//	LCD_Draw_Char('d', 0, 32);
//	LCD_Draw_Char(':', 0, 40);
//
//	LCD_Draw_Char('(', 1, 127-40);
//	LCD_Draw_Char('r', 1, 127-32);
//	LCD_Draw_Char('/', 1, 127-24);
//	LCD_Draw_Char('s', 1, 127-16);
//	LCD_Draw_Char(')', 1, 127-8);

	//Enable PB0
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0);
	GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0);

	while(1)
	{
		ADCProcessorTrigger(ADC_BASE, SequenceNum);

		// ȴȡת
		while(!ADCIntStatus(ADC_BASE, SequenceNum, false))
		{
		}

		// ADCжϱ־λ
		ADCIntClear(ADC_BASE, SequenceNum);

		// ȡADCֵ
		ADCSequenceDataGet(ADC_BASE, SequenceNum, pui32ADC0Value);

		adcWheel_value = pui32ADC0Value[0];

		// ǰתʽ
		cur_Duty = 5 + (90 * adcWheel_value) / MAX_ADC_VALUE;

		if((cur_Duty - old_Duty) > 1 || (old_Duty - cur_Duty) > 1)
		{
			uint32_t period = 0;

			period = (cur_Duty * SysCtlClockGet()) / 100;

			//
			ROM_IntDisable (INT_WTIMER0A);
			TimerLoadSet (WTIMER0_BASE, TIMER_A, period);
			ROM_IntEnable (INT_WTIMER0A);

			old_Duty = cur_Duty;
		}

		// ϵͳʱһִ4
		ROM_SysCtlDelay(SysCtlClockGet() / 12);

	}
}
//###############################################################################################
