/*********************************************************************
 *                  Flowcode CAL PWM File
 *
 * File: PIC16BIT_CAL_PWM.c
 *
 * (c) 2011 Matrix Multimedia Ltd.
 * http://www.matrixmultimedia.com
 *
 * Software License Agreement
 *
 * The software supplied herewith by Matrix Multimedia Ltd (the
 * “Company”) for its Flowcode graphical programming language is
 * intended and supplied to you, the Company’s customer, for use
 * solely and exclusively on the Company's products. The software
 * is owned by the Company, and is protected under applicable
 * copyright laws. All rights are reserved. Any use in violation
 * of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability
 * for the breach of the terms and conditions of this licence.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 * Changelog:
 *
 *  date  | by | description
 * -------+----+-----------------------------------------------------
 * 041011 | BR | Created
 * 050312 | BR | Updated to v5.1 CAL Schema
 * 290812 | BR | Added new FCD supplied code and upped max PWM count from 10 to 16
 * 040912 | BR | Added the MX_OCx definition to allow all families to work
 * 280912 | BR | Fixed an issue with PWM remappable defines
 * 011012 | BR | Added workaround for non working PWM on EP devices
 * 030713 | LM | Standard API calls
 */


#define MX_PWM_CHANNEL_X		CAL_APPEND(MX_PWM_CHANNEL_, MX_PWM_NUM)
#define MX_PWM_HWALT_X			CAL_APPEND(MX_PWM_HWALT_, 	MX_PWM_NUM)
#define MX_PWM_PORT_X			CAL_APPEND(MX_PWM_PORT_, 	MX_PWM_NUM)
#define MX_PWM_TRIS_X			CAL_APPEND(MX_PWM_TRIS_, 	MX_PWM_NUM)
#define MX_PWM_PIN_X			CAL_APPEND(MX_PWM_PIN_, 	MX_PWM_NUM)
#define MX_PWM_RPOR_X			CAL_APPEND(MX_PWM_RPOR_, 	MX_PWM_NUM)
#define MX_PWM_RPOC_X			CAL_APPEND(MX_PWM_RPOC_, 	MX_PWM_NUM)


//I2C Master Functions
CALFUNCTION(void, FC_CAL_PWM_Enable_, (void));
CALFUNCTION(void, FC_CAL_PWM_Disable_, (void));
CALFUNCTION(void, FC_CAL_PWM_SetDuty8Bit_, (MX_UINT8 duty));
CALFUNCTION(void, FC_CAL_PWM_ChangePeriod_, (MX_UINT8 period, MX_UINT16 prescaler));
CALFUNCTION(void, FC_CAL_PWM_SetDuty10Bit_, (MX_UINT16 duty));



CALFUNCTION(void, FC_CAL_PWM_Enable_, (void))
{

  #ifdef MX_PWM

	//Remappable PWM Functionality
	#ifdef MX_PWM_REMAPPABLE
		MX_PWM_RPOR_X = MX_PWM_RPOC_X;											//Assign PWM Channel OCx -> RPx - See FCD Defines For Info
	#endif

	#if (MX_PWM_HWALT_X == 0)													//Default PWM Pin
	  #ifndef MX_PWM_PORT_X														//Error checking
		#error "This chip does not have PWM channel 1 defined"
	  #endif
		FC_CAL_Bit_Low_DDR (MX_PWM_PORT_X, MX_PWM_TRIS_X, MX_PWM_PIN_X);		//PWM pin is an output
	#else																		//Alternate PWM Pin
	  #ifndef MX_PWM_PORTA_X													//Error checking
		#error "This chip does not have PWM alt channel 1 defined"
	  #endif
		FC_CAL_Bit_Low_DDR (MX_PWM_PORTA_A, MX_PWM_TRISA_X, MX_PWM_PINA_X);		//PWM pin is an output
	#endif

	#if (MX_PWM_CHANNEL_X == 1)

		#ifdef MX_PWM_OCxCON
			#define OC1CON OC1CON1
			#define MXWA
			OC1CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC1RS = 0;																//Enable Capture Compare Channel 1
		OC1R = 0;

		#ifdef MXWA
			OC1CON = 0x0005;
		#else
        	OC1CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 2)

		#ifdef MX_PWM_OCxCON
			#define OC2CON OC2CON1
			#define MXWA
			OC2CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC2RS = 0;																//Enable Capture Compare Channel 2
		OC2R = 0;

		#ifdef MXWA
			OC2CON = 0x0005;
		#else
        	OC2CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 3)

		#ifdef MX_PWM_OCxCON
			#define OC3CON OC3CON1
			#define MXWA
			OC3CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC3RS = 0;																//Enable Capture Compare Channel 3
		OC3R = 0;

		#ifdef MXWA
			OC3CON = 0x0005;
		#else
        	OC3CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 4)

		#ifdef MX_PWM_OCxCON
			#define OC4CON OC4CON1
			#define MXWA
			OC4CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC4RS = 0;																//Enable Capture Compare Channel 4
		OC4R = 0;

		#ifdef MXWA
			OC4CON = 0x0005;
		#else
        	OC4CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 5)

		#ifdef MX_PWM_OCxCON
			#define OC5CON OC5CON1
			#define MXWA
			OC5CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC5RS = 0;																//Enable Capture Compare Channel 5
		OC5R = 0;

		#ifdef MXWA
			OC5CON = 0x0005;
		#else
        	OC5CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 6)

		#ifdef MX_PWM_OCxCON
			#define OC6CON OC6CON1
			#define MXWA
			OC6CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC6RS = 0;																//Enable Capture Compare Channel 6
		OC6R = 0;

		#ifdef MXWA
			OC6CON = 0x0005;
		#else
        	OC6CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 7)

		#ifdef MX_PWM_OCxCON
			#define OC7CON OC3CON1
			#define MXWA
			OC7CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC7RS = 0;																//Enable Capture Compare Channel 7
		OC7R = 0;

		#ifdef MXWA
			OC7CON = 0x0005;
		#else
        	OC7CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 8)

		#ifdef MX_PWM_OCxCON
			#define OC8CON OC8CON1
			#define MXWA
			OC8CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC8RS = 0;																//Enable Capture Compare Channel 8
		OC8R = 0;

		#ifdef MXWA
			OC8CON = 0x0005;
		#else
        	OC8CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 9)

		#ifdef MX_PWM_OCxCON
			#define OC9CON OC9CON1
			#define MXWA
			OC9CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC9RS = 0;																//Enable Capture Compare Channel 9
		OC9R = 0;

		#ifdef MXWA
			OC9CON = 0x0005;
		#else
        	OC9CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 10)

		#ifdef MX_PWM_OCxCON
			#define OC10CON OC10CON1
			#define MXWA
			OC10CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC10RS = 0;																//Enable Capture Compare Channel 10
		OC10R = 0;

		#ifdef MXWA
			OC10CON = 0x0005;
		#else
        	OC10CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 11)

		#ifdef MX_PWM_OCxCON
			#define OC11CON OC11CON1
			#define MXWA
			OC11CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC11RS = 0;																//Enable Capture Compare Channel 11
		OC11R = 0;

		#ifdef MXWA
			OC11CON = 0x0005;
		#else
        	OC11CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 12)

		#ifdef MX_PWM_OCxCON
			#define OC12CON OC12CON1
			#define MXWA
			OC12CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC12RS = 0;																//Enable Capture Compare Channel 12
		OC12R = 0;

		#ifdef MXWA
			OC12CON = 0x0005;
		#else
        	OC12CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 13)

		#ifdef MX_PWM_OCxCON
			#define OC13CON OC13CON1
			#define MXWA
			OC13CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC13RS = 0;																//Enable Capture Compare Channel 13
		OC13R = 0;

		#ifdef MXWA
			OC13CON = 0x0005;
		#else
        	OC13CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 14)

		#ifdef MX_PWM_OCxCON
			#define OC14CON OC14CON1
			#define MXWA
			OC14CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC14RS = 0;																//Enable Capture Compare Channel 14
		OC14R = 0;

		#ifdef MXWA
			OC14CON = 0x0005;
		#else
        	OC14CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 15)

		#ifdef MX_PWM_OCxCON
			#define OC15CON OC15CON1
			#define MXWA
			OC15CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC15RS = 0;																//Enable Capture Compare Channel 15
		OC15R = 0;

		#ifdef MXWA
			OC15CON = 0x0005;
		#else
        	OC15CON = 0x0006;
        #endif
	#endif

	#if (MX_PWM_CHANNEL_X == 16)

		#ifdef MX_PWM_OCxCON
			#define OC16CON OC16CON1
			#define MXWA
			OC16CON2 = 0x000C;			//Timer 2 is clock source
		#endif

		OC16RS = 0;																//Enable Capture Compare Channel 16
		OC16R = 0;

		#ifdef MXWA
			OC16CON = 0x0005;
		#else
        	OC16CON = 0x0006;
        #endif
	#endif

  #else
 	#error "Hardware PWM not supported by Target microcontroller."
  #endif
}


CALFUNCTION(void, FC_CAL_PWM_Disable_, (void))
{

	#if (MX_PWM_HWALT_X == 0)														//Default PWM Pin
		FC_CAL_Bit_In_DDR (MX_PWM_PORT_X, MX_PWM_TRIS_X, MX_PWM_PIN_X);				//PWM pin is an input
	#else																			//Alternate PWM Pin
		FC_CAL_Bit_In_DDR (MX_PWM_PORTA_X, MX_PWM_TRISA_X, MX_PWM_PINA_X);			//PWM pin is an input
	#endif


	#if (MX_PWM_CHANNEL_X == 1)
		OC1CON = 0;																	//Disable Capture Compare Channel 1
	#endif

	#if (MX_PWM_CHANNEL_X == 2)
		OC2CON = 0;																	//Disable Capture Compare Channel 2
	#endif

	#if (MX_PWM_CHANNEL_X == 3)
		OC3CON = 0;																	//Disable Capture Compare Channel 3
	#endif

	#if (MX_PWM_CHANNEL_X == 4)
		OC4CON = 0;																	//Disable Capture Compare Channel 4
	#endif

	#if (MX_PWM_CHANNEL_X == 5)
		OC5CON = 0;																	//Disable Capture Compare Channel 5
	#endif

	#if (MX_PWM_CHANNEL_X == 6)
		OC6CON = 0;																	//Disable Capture Compare Channel 6
	#endif

	#if (MX_PWM_CHANNEL_X == 7)
		OC7CON = 0;																	//Disable Capture Compare Channel 7
	#endif

	#if (MX_PWM_CHANNEL_X == 8)
		OC8CON = 0;																	//Disable Capture Compare Channel 8
	#endif

	#if (MX_PWM_CHANNEL_X == 9)
		OC9CON = 0;																	//Disable Capture Compare Channel 9
	#endif

	#if (MX_PWM_CHANNEL_X == 10)
		OC10CON = 0;																	//Disable Capture Compare Channel 10
	#endif

	#if (MX_PWM_CHANNEL_X == 11)
		OC11CON = 0;																	//Disable Capture Compare Channel 11
	#endif

	#if (MX_PWM_CHANNEL_X == 12)
		OC12CON = 0;																	//Disable Capture Compare Channel 12
	#endif

	#if (MX_PWM_CHANNEL_X == 13)
		OC13CON = 0;																	//Disable Capture Compare Channel 13
	#endif

	#if (MX_PWM_CHANNEL_X == 14)
		OC14CON = 0;																	//Disable Capture Compare Channel 14
	#endif

	#if (MX_PWM_CHANNEL_X == 15)
		OC15CON = 0;																	//Disable Capture Compare Channel 15
	#endif

	#if (MX_PWM_CHANNEL_X == 16)
		OC16CON = 0;																	//Disable Capture Compare Channel 16
	#endif
}


CALFUNCTION(void, FC_CAL_PWM_SetDuty8Bit_, (MX_UINT8 nDuty))
{
	#if (MX_PWM_CHANNEL_X == 1)
		OC1RS = nDuty;						//Update Capture Compare Count 1
	#endif

	#if (MX_PWM_CHANNEL_X == 2)
		OC2RS = nDuty;						//Update Capture Compare Count 2
	#endif

	#if (MX_PWM_CHANNEL_X == 3)
		OC3RS = nDuty;						//Update Capture Compare Count 3
	#endif

	#if (MX_PWM_CHANNEL_X == 4)
		OC4RS = nDuty;						//Update Capture Compare Count 4
	#endif

	#if (MX_PWM_CHANNEL_X == 5)
		OC5RS = nDuty;						//Update Capture Compare Count 5
	#endif

	#if (MX_PWM_CHANNEL_X == 6)
		OC6RS = nDuty;						//Update Capture Compare Count 6
	#endif

	#if (MX_PWM_CHANNEL_X == 7)
		OC7RS = nDuty;						//Update Capture Compare Count 7
	#endif

	#if (MX_PWM_CHANNEL_X == 8)
		OC8RS = nDuty;						//Update Capture Compare Count 8
	#endif

	#if (MX_PWM_CHANNEL_X == 9)
		OC9RS = nDuty;						//Update Capture Compare Count 9
	#endif

	#if (MX_PWM_CHANNEL_X == 10)
		OC10RS = nDuty;						//Update Capture Compare Count 10
	#endif

	#if (MX_PWM_CHANNEL_X == 11)
		OC11RS = nDuty;						//Update Capture Compare Count 11
	#endif

	#if (MX_PWM_CHANNEL_X == 12)
		OC12RS = nDuty;						//Update Capture Compare Count 12
	#endif

	#if (MX_PWM_CHANNEL_X == 13)
		OC13RS = nDuty;						//Update Capture Compare Count 13
	#endif

	#if (MX_PWM_CHANNEL_X == 14)
		OC14RS = nDuty;						//Update Capture Compare Count 14
	#endif

	#if (MX_PWM_CHANNEL_X == 15)
		OC15RS = nDuty;						//Update Capture Compare Count 15
	#endif

	#if (MX_PWM_CHANNEL_X == 16)
		OC16RS = nDuty;						//Update Capture Compare Count 16
	#endif
}


CALFUNCTION(void, FC_CAL_PWM_ChangePeriod_, (MX_UINT8 period, MX_UINT16 prescaler))
{
  #ifdef MX_PWM								//Hardware Mode

	PR2 = period;
	switch (prescaler)
	{
		default:
			T2CON = 0x8000;
			break;
		case 8:
		case 1:
			T2CON = 0x8010;
			break;
		case 64:
		case 2:
			T2CON = 0x8020;
			break;
		case 256:
		case 3:
			T2CON = 0x8030;
			break;
	}

  #endif
}


CALFUNCTION(void, FC_CAL_PWM_SetDuty10Bit_, (MX_UINT16 duty))
{
	#if (MX_PWM_CHANNEL_X == 1)
		OC1RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 2)
		OC2RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 3)
		OC3RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 4)
		OC4RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 5)
		OC5RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 6)
		OC6RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 7)
		OC7RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 8)
		OC8RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 9)
		OC9RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 10)
		OC10RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 11)
		OC11RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 12)
		OC12RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 13)
		OC13RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 14)
		OC14RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 15)
		OC15RS = (duty >> 2);
	#endif

	#if (MX_PWM_CHANNEL_X == 16)
		OC16RS = (duty >> 2);
	#endif
}

