/** ###################################################################
**     Filename    : ProcessorExpert.c
**     Project     : ProcessorExpert
**     Processor   : MC56F84789VLL
**     Version     : Driver 01.14
**     Compiler    : Metrowerks DSP C Compiler
**     Date/Time   : 2012-02-15, 21:48, # CodeGen: 0
**     Abstract    :
**         Main module.
**         This module contains user's application code.
**     Settings    :
**     Contents    :
**         No public methods
**
** ###################################################################*/
/* MODULE ProcessorExpert */


/* Including needed modules to compile this module/procedure */
#include "Cpu.h"
#include "Events.h"
#include "CyclicADC.h"
#include "TMR1.h"
#include "COP1.h"
#include "LEDs0to7.h"
#include "IdleLamp.h"
#include "DFR1.h"
#include "ForADC12Atrigger.h"
#include "FMSTR1.h"
#include "Inhr2.h"
#include "Inhr3.h"
/* Including shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"



/* use const to output FIR filter coefficients
 to the data section to be placed in data memory.*/
const
#include "FirCoefs.h" 

#define DIFF_TS 20
#define BUFF_SIZE 20
#define SWTMR_TOUT 400
#define _100MS	100
#define RT1ONTH	-15
#define RT1OFFTH 10
#define RT2ONTH	-80
#define RT2OFFTH 40
#define RT3ONTH -70
#define RT3OFFTH 30
#define RT4ONTH -80
#define RT4OFFTH 40


/* LED control bits */
typedef union
{
	struct
	{
	  unsigned int rt1on   		  : 1; /* RT1ON */
	  unsigned int rt2on		  : 1; /* RT2ON */
	  unsigned int rt3on          : 1; /* RT3ON */
	  unsigned int rt4on		  : 1; /* RT4ON */
	  unsigned int idleloop		  : 1; /* RESERVED */
	  unsigned int Bit5           : 1; /* RESERVED */
	  unsigned int Bit6           : 1; /* RESERVED */
	  unsigned int Bit7           : 1; /* RESERVED */
	  unsigned int Bit8           : 1; /* RESERVED */
	  unsigned int Bit9           : 1; /* RESERVED */
	  unsigned int Bit10          : 1; /* RESERVED */
	  unsigned int Bit11          : 1; /* RESERVED */
	  unsigned int Bit12          : 1; /* RESERVED */
	  unsigned int Bit13          : 1; /* RESERVED */
	  unsigned int Bit14          : 1; /* RESERVED */
	  unsigned int Bit15          : 1; /* RESERVED */
	} B;
UWord16 W16;
} BIT_CONTROL_T;     /* LED Control bits */


/* Global variables */
UWord16 swDiffCNTR, swTimerCNTR;
BIT_CONTROL_T rton;
UWord16 rt_filter_on;
UWord16 rt_filter_off;
UWord16 timeout;
Word16 rt1_filt_buff[BUFF_SIZE], rt2_filt_buff[BUFF_SIZE];
Word16 rt3_filt_buff[BUFF_SIZE], rt4_filt_buff[BUFF_SIZE];
UWord16 i_delay = 1, i_sample = 0;

/* FIR Filter Variables */
dfr16_tFirStruct * pFIR1;
dfr16_tFirStruct * pFIR2;
dfr16_tFirStruct * pFIR3;
dfr16_tFirStruct * pFIR4;
dfr16_tFirStruct    FIR1,FIR2,FIR3,FIR4;
Frac16 FIR1_History[31];
Frac16 FIR2_History[31];
Frac16 FIR3_History[31];
Frac16 FIR4_History[31];
//typedef struct dfr16_sFirStruct {
// Frac16   * pC;                 /* Coefficients for the filter */
// Frac16   * pHistory;           /* Memory for the filter history buffer */
// UWord16    Private[6];
//} 
/*********************************************/
/* ADC End of Scan interrupt service routine */
/* execution period = 1ms										 */
/*********************************************/
#pragma interrupt saveall on
void ADC_EndofScanISR(void)
{
  Word16 rt1, rt2, rt3, rt4;
  Word16 rt1_filt, rt2_filt, rt3_filt, rt4_filt;
  Word16 delta_rt1, delta_rt2;
  Word16 delta_rt3, delta_rt4;

  rt1 = (short) PESL(ADC12, ADC_READ_SAMPLE, 8);
  rt2 = (short) PESL(ADC12, ADC_READ_SAMPLE, 9);
  rt3 = (short) PESL(ADC12, ADC_READ_SAMPLE, 1);
  rt4 = (short) PESL(ADC12, ADC_READ_SAMPLE, 0);
  
  /* Execute FIR filter on ADC samples */
    DFR1_dfr16FIR( pFIR1, &rt1, &rt1_filt, 1);
 	DFR1_dfr16FIR( pFIR2, &rt2, &rt2_filt, 1);
 	DFR1_dfr16FIR( pFIR3, &rt3, &rt3_filt, 1);
 	DFR1_dfr16FIR( pFIR4, &rt4, &rt4_filt, 1);
	
	
	/*Reset SWSamplerCNT*/
	if(swDiffCNTR >= DIFF_TS)
	{
	
		/* evaluate delta */
		delta_rt1 = rt1_filt - rt1_filt_buff[i_delay];
		delta_rt2 = rt2_filt - rt2_filt_buff[i_delay];
		delta_rt3 = rt3_filt - rt3_filt_buff[i_delay];
		delta_rt4 = rt4_filt - rt4_filt_buff[i_delay];
		
		/* store samples in the buffer */
		rt1_filt_buff[i_sample] = rt1_filt;
		rt2_filt_buff[i_sample] = rt2_filt;
		rt3_filt_buff[i_sample] = rt3_filt;
		rt4_filt_buff[i_sample] = rt4_filt;
		if(++i_sample>=BUFF_SIZE) i_sample = 0;
		if(++i_delay>=BUFF_SIZE) i_delay = 0;

		/* detect rt ON/OFF */
		/* Three consequent samples has to be higher than threshold limit */
		/* rt1 ON filter */
		if(delta_rt1<RT1ONTH)
		{	rt_filter_on+=0x1;
			if((rt_filter_on&0xf)>=0x3)
			{	rt_filter_on&=~0xf;
				rton.B.rt1on = 1;	}	}
		else	rt_filter_on&=~0xf;	
		/* rt1 OFF filter */
		if(delta_rt1>RT1OFFTH)
		{	rt_filter_off+=0x1;
			if((rt_filter_off&0xf)>=0x3)
			{	rt_filter_off&=~0xf;
				rton.W16 &= ~0xf;	}	}
		else	rt_filter_off&=~0xf;	
		/* rt2 ON filter */
		if(delta_rt2<RT2ONTH)
		{	rt_filter_on+=0x10;
			if((rt_filter_on&0xf0)>=0x30)
			{	rt_filter_on&=~0xf0;
				rton.B.rt2on = 1;	}	}
		else	rt_filter_on&=~0xf0;
		/* rt2 OFF filter */
		if(delta_rt2>RT2OFFTH)
		{	rt_filter_off+=0x10;
			if((rt_filter_off&0xf0)>=0x30)
			{	rt_filter_off&=~0xf0;
				rton.W16 &= ~0xf;	}	}
		else	rt_filter_off&=~0xf0;		
		/* rt3 ON filter */
		if(delta_rt3<RT3ONTH)
		{	rt_filter_on+=0x100;
			if((rt_filter_on&0xf00)>=0x300)
			{	rt_filter_on&=~0xf00;
				rton.B.rt3on = 1;	}	}
		else	rt_filter_on&=~0xf00;
		/* rt3 OFF filter */
		if(delta_rt3>RT3OFFTH)
		{	rt_filter_off+=0x100;
			if((rt_filter_off&0xf00)>=0x300)
			{	rt_filter_off&=~0xf00;
				rton.W16 &= ~0xf;	}	}
		else	rt_filter_off&=~0xf00;

		/* rt4 ON filter */
		if(delta_rt4<RT4ONTH)
		{	rt_filter_on+=0x1000;
			if((rt_filter_on&0xf000)>=0x3000)
			{	rt_filter_on&=~0xf000;
				rton.B.rt4on = 1;	}	}
		else	rt_filter_on&=~0xf000;
		/* rt4 OFF filter */
		if(delta_rt4>RT4OFFTH)
		{	rt_filter_off+=0x1000;
			if((rt_filter_off&0xf000)>=0x3000)
			{	rt_filter_off&=~0xf000;
				rton.W16 &= ~0xf;	}	}
		else	rt_filter_off&=~0xf000;
			
		/* reset counter */
		swDiffCNTR = 0;
	}
	else
	{
		swDiffCNTR++;
	}
	
		/* Reset SWTimerCNTR every 400ms */
		/* Software timer is used to control LED flashing intervals */
	if(swTimerCNTR >= SWTMR_TOUT)
	{
		swTimerCNTR = 0;
	}
	else
	{
		swTimerCNTR++;
	}
	
	if(swTimerCNTR == timeout)
	{
		rton.B.idleloop = 0;
		timeout += _100MS; /* time out event every 100 ms */
		if(timeout >= SWTMR_TOUT) timeout = 0;

	}
//	PESL(ADC, ADC_CLEAR_STATUS_EOSI, NULL);	
	PESL(ADC12, ADC_CLEAR_STATUS_EOSI, NULL);
}

/*********************************************/
/* Application main() function               */
/*                      										 */
/*********************************************/
void main(void)
{
  /* Write your local variable definition here */
	Frac16 * pC;
	
  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  PE_low_level_init();

  
 /*** End of Processor Expert internal initialization.                    ***/
  
  
// Need timer B0 to trigger the ADC conversion process.  This is connected through the peripheral cross bar peripheral, XBAR.  
  PESL(XBARA, XBAR_OUT12_INPUT_SEL, SYS_XBAR_IN16); // TMRB0 trigger ADC12 A

  /* ADC Peripheral Bean Workaround GPIO_A_PEREN: PE7=1, PE6=1, PE5=1, PE4=1 */
  setReg16Bits(GPIOA_PER, 0xf0U);    
  /* ADC Peripheral Bean Workaround GPIO_B_PEREN: PE7=1, PE6=1, PE5=1, PE4=1 */
  setReg16Bits(GPIOB_PER, 0xf0U);    
  
	/* Initialize FIR filter data structures in static memory */
  pC = (Frac16 *) FirCoefs ;
  pFIR1 = &FIR1;
  pFIR2 = &FIR2;
  pFIR3 = &FIR3;
  pFIR4 = &FIR4;
  FIR1.pC = (  Frac16  *)  FirCoefs ;
  FIR1.pHistory = (Frac16 *) FIR1_History ;
  FIR2.pC = (Frac16 *)  FirCoefs ;
  FIR2.pHistory = (Frac16 *) FIR2_History ;
  FIR3.pC = (Frac16 *)  FirCoefs ;
  FIR3.pHistory = (Frac16 *) FIR3_History ;
  FIR4.pC = (Frac16 *)  FirCoefs ;
  FIR4.pHistory = (Frac16 *) FIR4_History ;
  
	/* Initialize FIR bank.  */
	dfr16FIRInit (pFIR1, pC, 31);
	dfr16FIRInit (pFIR2, pC, 31);
	dfr16FIRInit (pFIR3, pC, 31);
	dfr16FIRInit (pFIR4, pC, 31);
   
	/* Clear Watch Dog */
    PESL(COP, COP_CLEAR_COUNTER, NULL);

    /* wait for ADC to power up */
    while (PESL(ADC12, ADC_GET_POWER_STATUS, ADC_CONVERTER_0 | ADC_CONVERTER_1)) {};

    /* clear ADC status and enable ADC Conversion Complete interrupts */
	PESL(ADC12, ADC_CLEAR_STATUS_EOSI, NULL);
    PESL(ADC12, ADC_INT_ENABLE, ADC_END_OF_SCAN);

    /* Start ADC conversion */
	PESL(ADC12, ADC_STOP, ADC_OFF);
	
	/* wait until rtx_filt_buffers are initialized  */
 	while(swTimerCNTR<350) {};

 	/* Clear Watch Dog */
 	PESL(COP, COP_CLEAR_COUNTER, NULL);
 	while(swTimerCNTR<350) {};
 	rton.W16 &= ~0xF;

 	/* Clear Watch Dog */
 	PESL(COP, COP_CLEAR_COUNTER, NULL);
  for(;;) 
  {
		/* idle loop, waiting for timeout */
		while (rton.B.idleloop == 1) {};
		
		/* Timing of LED flashing */			
		switch(timeout)
		{
		case 0:
			PESL(GPIOE, GPIO_WRITE_DATA, 0x33);
			if(rton.B.rt1on)  PESL(GPIOE, GPIO_WRITE_DATA, 0x3);
			if(rton.B.rt2on)  PESL(GPIOE, GPIO_WRITE_DATA, 0xC);
			if(rton.B.rt3on)  PESL(GPIOE, GPIO_WRITE_DATA, 0x30);
			if(rton.B.rt4on)  PESL(GPIOE, GPIO_WRITE_DATA, 0xC0);			
			break;
		case 100:
			if(rton.W16&0xf)  PESL(GPIOE, GPIO_CLEAR_PIN, 0xff);
    	break;
		case 200:
			PESL(GPIOE, GPIO_WRITE_DATA, 0xcc);
			if(rton.B.rt1on)  PESL(GPIOE, GPIO_WRITE_DATA, 0x3);
			if(rton.B.rt2on)  PESL(GPIOE, GPIO_WRITE_DATA, 0xC);
			if(rton.B.rt3on)  PESL(GPIOE, GPIO_WRITE_DATA, 0x30);
			if(rton.B.rt4on)  PESL(GPIOE, GPIO_WRITE_DATA, 0xC0);			
    	break;
		case 300:
			if(rton.W16&0xf)  PESL(GPIOE, GPIO_CLEAR_PIN, 0xff);
			break;
		default:
			break;
		}
		rton.B.idleloop = 1;
		/* Clear Watch Dog */
      PESL(COP, COP_CLEAR_COUNTER, ...);
      FMSTR1_Poll();
  }
}

/* END ProcessorExpert */
/*
** ###################################################################
**
**     This file was created by Processor Expert 5.3 [05.01]
**     for the Freescale 56800 series of microcontrollers.
**
** ###################################################################
*/
