/*********************************************************************
 *                    Flowcode PWM Component Code
 *
 * File: PIC16BIT_PWM.c
 *
 * (c) 2010 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
 * -------+----+-----------------------------------------------------
 * 260207 | ST | Created
 * 010307 | ST | Changed due to 2 PWMs within 1 component
 * 250309 | BR | Added 10-bit PWM functionality
 * 130509 | BR | Added % definitions to DefinesCode section
 * 290609 | SK | SetDutyCycle10bit - CCPxCON code moved inside nIdx test blocks. CCPxCONtemp variable added to prevent multiple read-modify-writes on working registers.
 * 131109 | BR | Fixed #pragma error HITECH problem
 * 300710 | SK | Converted to PIC16BIT
 * 100910 | BR | Updated to work with reallocatable pins
 * 290910 | BR | Init code now works with allocatable pins
 ********************************************************************/

/*********************************************************************

 Return & parameter types:
   void
   char
   short
   char*

 Pin directions:
   0 = OUTPUT
   2 = INPUT
   3 = BIDIRECTIONAL

**********************************************************************

[Settings]
CLSID={78F46BA6-E118-42D2-AF9E-22B628E3248E}
IsAnalogue=0
MultipleAllowed=0
Description=PWM

**********************************************************************

[Port]
DesiredPort=0
PortMandatory=0
SamePortAsID=0

[Pins]
Count=0
1=
2=
3=
4=

[PinDirection]
1=
2=
3=
4=

[PinDesiredBit]
1=
2=
3=
4=

[BitMandatory]
1=
2=
3=
4=

**********************************************************************

[MacroNames]
Count=5
1=Enable
2=Disable
3=SetDutyCycle
4=ChangePeriod
5=SetDutyCycle10bit

[MacroReturns]
1=void
2=void
3=void
4=void
5=void

[MacroIsPrivate]
1=0
2=0
3=0
4=0
5=0

[MacroParameters_Enable]
Count=1
1=nIdx

[MacroParamTypes_Enable]
1=char

[MacroParameters_Disable]
Count=1
1=nIdx

[MacroParamTypes_Disable]
1=char

[MacroParameters_SetDutyCycle]
Count=2
1=nIdx
2=nDuty

[MacroParamTypes_SetDutyCycle]
1=char
2=char

[MacroParameters_ChangePeriod]
Count=2
1=nPeriodVal
2=nPrescalerVal

[MacroParamTypes_ChangePeriod]
1=char
2=char

[MacroParameters_SetDutyCycle10bit]
Count=2
1=nIdx
2=nDuty

[MacroParamTypes_SetDutyCycle10bit]
1=char
2=short

 ********************************************************************/

/********************************************************************
 * ADDITIONAL CODE
 ********************************************************************/

/*DefinesCode_Start*/

/**** Macro Substitutions ****
%a = Timer 2 Rollover Value
%b = Timer 2 Prescaler Value
%c = Unused
%d = Alternate Pin Enable
******************************/

/*DefinesCode_End*/

/*InitialisationCode_Start*/

//Remappable PWM Functionality
#ifdef MX_PWM_PORT_FREEALLOC

	//configure remapping
	RPOR0 = (RPOR0 & 0xFF00) | 0x0012;		//Assign PWM OC1 - RP0 / PORTB0
	RPOR0 = (RPOR0 & 0x00FF) | 0x1300;		//Assign PWM OC2 - RP1 / PORTB1
	RPOR1 = (RPOR1 & 0xFF00) | 0x0014; 		//Assign PWM OC3 - RP2 / PORTB2
	RPOR1 = (RPOR1 & 0x00FF) | 0x1500; 		//Assign PWM OC4 - RP3 / PORTB3

#endif

//Explorer 16 Remappable PWM Functionality
#ifdef MX_PWM_PORT_E16ALLOC

	//configure remapping
	RPOR4 = (RPOR4 & 0x00FF) | 0x1200;		//Assign PWM OC1 - RP9  / PORTB9
	RPOR6 = (RPOR6 & 0xFF00) | 0x0013;		//Assign PWM OC2 - RP12 / PORTB12

#endif

/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/

/********************************************************************
 * FUNCTIONS
 ********************************************************************/


void Enable(char nIdx)
{
/*Macro_Enable_Start*/

  //error checking
  #ifndef MX_PWM
	#error This chip does not have PWM capability
  #else
    #ifndef MX_PWM_CNT
		#error FCD file error (no MX_PWM_CNT)
    #endif

    #if (MX_PWM_CNT < 1)
		#error FCD file error (MX_PWM_CNT < 1)
    #endif

    #if (MX_PWM_CNT >= 2)
      #ifndef MX_PWM_2
		#error FCD file error (no MX_PWM_2)
      #endif
    #endif
  #endif

 #ifdef MX_PWM
    PR2 = %a;
    T2CON = %b;

  #if (MX_PWM_CNT >= 1)
    if (nIdx == 1)
    {
		OC1RS = 0;
		OC1R = 0;
        OC1CON = 0x0006;
	}
  #endif

  #if (MX_PWM_CNT >= 2)
    if (nIdx == 2)
    {
		OC2RS = 0;
		OC2R = 0;
        OC2CON = 0x0006;
   }
  #endif
  
  #if (MX_PWM_CNT >= 3)
    if (nIdx == 3)
    {
		OC3RS = 0;
		OC3R = 0;
        OC3CON = 0x0006;
   }
  #endif
  #if (MX_PWM_CNT >= 4)
    if (nIdx == 4)
    {
		OC4RS = 0;
		OC4R = 0;
        OC4CON = 0x0006;
   }
  #endif
 #endif

/*Macro_Enable_End*/
}



void Disable(char nIdx)
{
/*Macro_Disable_Start*/

 #ifdef MX_PWM
  #if (MX_PWM_CNT >= 1)
    if (nIdx == 1)
    {
        OC1CON = 0x00;
    }
  #endif

  #if (MX_PWM_CNT >= 2)
    if (nIdx == 2)
    {
        OC2CON = 0x00;
    }
  #endif
  
  #if (MX_PWM_CNT >= 3)
    if (nIdx == 3)
    {
        OC3CON = 0x00;
    }
  #endif
  
  #if (MX_PWM_CNT >= 4)
    if (nIdx == 4)
    {
        OC4CON = 0x00;
    }
  #endif
 #endif

/*Macro_Disable_End*/
}


void SetDutyCycle(char nIdx, char nDuty)
{
/*Macro_SetDutyCycle_Start*/

 #ifdef MX_PWM
  #if (MX_PWM_CNT >= 1)
    if (nIdx == 1)
    {
        OC1RS = nDuty;
    }
  #endif

  #if (MX_PWM_CNT >= 2)
    if (nIdx == 2)
    {
        OC2RS = nDuty;
    }
  #endif
  
  #if (MX_PWM_CNT >= 3)
    if (nIdx == 3)
    {
        OC3RS = nDuty;
    }
  #endif
  
  #if (MX_PWM_CNT >= 4)
    if (nIdx == 4)
    {
        OC4RS = nDuty;
    }
  #endif
 #endif

/*Macro_SetDutyCycle_End*/
}



void ChangePeriod(char nPeriodVal, char nPrescalerVal)
{
/*Macro_ChangePeriod_Start*/

  #ifdef MX_PWM
    PR2 = nPeriodVal;

    switch (nPrescalerVal)
    {
        case 0:
            T2CON = 0x8000;
            break;

        case 1:
            T2CON = 0x8010;
            break;

        case 2:
            T2CON = 0x8020;
            break;

        case 3:
            T2CON = 0x8030;
            break;
    }
  #endif

/*Macro_ChangePeriod_End*/
}


void SetDutyCycle10bit(char nIdx, short nDuty)
{
/*Macro_SetDutyCycle10bit_Start*/

 #ifdef MX_PWM
  #if (MX_PWM_CNT >= 1)
    if (nIdx == 1)
    {
        OC1RS = (nDuty >> 2);
    }
  #endif

  #if (MX_PWM_CNT >= 2)
    if (nIdx == 2)
    {
        OC2RS = (nDuty >> 2);
    }
  #endif
  
  #if (MX_PWM_CNT >= 3)
    if (nIdx == 3)
    {
        OC3RS = (nDuty >> 2);
    }
  #endif
  
  #if (MX_PWM_CNT >= 4)
    if (nIdx == 4)
    {
        OC4RS = (nDuty >> 2);
    }
  #endif
 #endif

/*Macro_SetDutyCycle10bit_End*/
}

