/*****************************************************************************
 *   pwm.c:  PWM module file for NXP LPC29xx Family Microprocessors
 *
 *   Copyright(C) 2009, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2009.12.71  ver 1.00    Preliminary version, first Release
 *
 ****************************************************************************
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 *****************************************************************************/

#include "LPC29xx.h"                        /* LPC29xx definitions */
#include "type.h"
#include "irq.h"
#include "pwm.h"
#include "FOC.h"
#include "dma.h"

extern volatile FOC_STRUCT FOC;

/******************************************************************************
** Function name:		PWM0Handler
**
** Descriptions:		PWM interrupt handler
**						
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void PWM0Handler (void)
{
	PWM0_INT_CLR_STATUS |= PWM0_INT_STATUS;
  	return;
}

/******************************************************************************
** Function name:		PWM0Handler
**
** Descriptions:		PWM capture Match interrupt handler
**						
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void PWM0CapMatchHandler (void)
{
	DWORD regVal;
	
	regVal = PWM0_INTM_STATUS;
	if(regVal&(1<<1))				// check on match1 : first phase high side
	{
		MTIM0_MR0 = PWM_CYCLE;		// Set MATCHx register
		MTIM0_TCR = (1<<1);			// Counter reset 
  		MTIM0_TCR &= ~(1<<1);
	  	MTIM0_TCR |= (1<<0);		// Enable counter
	}
	else if(regVal&(1<<3))			// check on match3 : second phase high side
	{
		MTIM0_MR0 = PWM_CYCLE;		// Set MATCHx register
		MTIM0_TCR = (1<<1);			// Counter reset 
  		MTIM0_TCR &= ~(1<<1);
  		MTIM0_TCR |= (1<<0);		// Enable counter
	}
	
	PWM0_INTM_CLR_STATUS |= regVal;
	return;
}

/******************************************************************************
** Function name:	PWM_Init
**
** Descriptions:	PWM initialization, reset counter, all latches are 
**					enabled, interrupt on PWMMR0, install PWM interrupt 
**					to the VIC table.
**
** parameters:		Duty cycle
** Returned value:	None
** 
******************************************************************************/
void PWM0_Init(void)
{
	BYTE i;
		
  	// Define PWM channels 
  	SFSP2_8 = (0x05<<2)|(0x02<<0); 	// Digital no PU and PD, func. 2, PWM0 MAT0 =  HIN_N1
	SFSP2_9 = (0x05<<2)|(0x02<<0);  // Digital no PU and PD, func. 2, PWM0 MAT1 =  LIN_N1
	SFSP2_10 = (0x05<<2)|(0x02<<0); // Digital no PU and PD, func. 2, PWM0 MAT2 =  HIN_N2
	SFSP2_11 = (0x05<<2)|(0x02<<0); // Digital no PU and PD, func. 2, PWM0 MAT3 =  LIN_N2	
  	SFSP2_12 = (0x05<<2)|(0x02<<0); // Digital no PU and PD, func. 2, PWM0 MAT4 =  HIN_N3
  	SFSP2_13 = (0x05<<2)|(0x02<<0);	// Digital no PU and PD, func. 2, PWM0 MAT5 =  LIN_N3
  	 
  	PWM0_Stop();
	// PWM0 Output period is (PRD+1)*(PRSC+1) system clock cycles. 120=1MHz, 1200=100kHz, 12000=10kHz 	
	PWM0_PRSC = 0;							// prescale 0 : 120 MHz  	
	PWM0_PRD = PWM_CYCLE;					// period	
	for(i=0;i<6;i++)FOC.mACT[i]=0xFFFF;		// pwm=0%
	PWM0_Set();		
  	
  	PWM0_TRPCTL &= ~( PWM_MATCH0_5|(0x01<<16) );	// Trap polarity: active low, disable traps on PWM0~5 	 	
	PWM0_MODECTL &= ~(RUN_ONCE);					// Continuous mode
	PWM0_SYNDEL = 0;
	PWM0_MODECTL |= (UPD_ENA|SYNC_SEL|TRANS_ENA_SEL|SYNC_OUT_ENA|CNT_ENA);	// Transfer trigger external. Sync with mtimer0	
	PWM0_CTRL |= (1<<4)|(1<<2)|(1<<0);				// 0,2,4 active-high, 
	PWM0_CTRL &= ~((1<<5)|(1<<3)|(1<<1));			// 1,3,5 active-low
	PWM0_CTRL &= ~(PWM_MATCH0_5<<16);				// 0~5 carrier burst disabled, reset value 
  	return;
}

/******************************************************************************
** Function name:		PWM0_Set
**
** Descriptions:		PWM match activate and deactivate registers setup 
**
** parameters:			FOC struct
** Returned value:		None
** 
******************************************************************************/
void PWM0_Set( void )
{
  	BYTE i;
	for(i=0;i<6;i++)
	{
		*(volatile unsigned long *) (PWM0_MATCHA0_ADR + (i<<2))	= FOC.mACT[i];	// Set PWM0 activate register
		*(volatile unsigned long *) (PWM0_MATCHDA0_ADR + (i<<2))= FOC.mDACT[i];	// Set PWM0 deactivate register
	}
 
  	PWM0_MODECTL |= UPD_ENA;
  	PWM0_MODECTL |= TRANS_ENA;		// Transfer and update shadow registers 
  	return;
}

/******************************************************************************
** Function name:		PWM_Start
**
** Descriptions:		Start PWM
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void PWM0_Start( void )
{
  	PWM0_MODECTL |= CNT_RESET;		// Counter Reset 
  	PWM0_MODECTL &= ~CNT_RESET;
	
  	// Start from reset value, enable update and transfer 
  	PWM0_MODECTL |= UPD_ENA|TRANS_ENA;	
  	PWM0_MODECTL |= CNT_ENA;		// Counter enable, PWM enable 
  	PWM0_MODECTL |= UPD_ENA;
	
	PWM0_INT_SET_ENABLE = CO_INT; 	// Enable PWM interrupt 

  return;
}

/******************************************************************************
** Function name:		PWM_Stop
**
** Descriptions:		Stop PWM
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void PWM0_Stop( void )
{
  PWM0_MODECTL |= CNT_RESET;	/* Counter Reset */
  PWM0_MODECTL &= ~CNT_RESET;

  // All disabled UPD, TRANS, SYNC_OUT and COUNTER 
  PWM0_MODECTL &= ~(CNT_ENA|SYNC_OUT_ENA|TRANS_ENA);	// Stop PWM 
  PWM0_MODECTL |= UPD_ENA;
  return;
}

/******************************************************************************
** Function name:		PWM_Reset
**
** Descriptions:		Reset PWM
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void PWM0_Reset( void )
{
  PWM0_MODECTL |= CNT_RESET;	// Counter Reset 
  PWM0_MODECTL &= ~CNT_RESET;

  // Clear pending interrpt 
  PWM0_INT_CLR_STATUS = 0x0F;	// Clear EMGY, UD, TD, and CO 
  PWM0_INTM_CLR_STATUS = 0xFFF;	// Clear match act 0~5, match deact 0-5
  PWM0_INTC_CLR_STATUS = 0x0F;	// Clear capture 0~3
  return;
}

/******************************************************************************
**                            End Of File
******************************************************************************/
