/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   PWM Resource Framework API Header File
::   Copyright   :   (C)2002-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file Resource_PWM.h
    \brief The BEHAVIOUR_PWM behaviour provides pulse width modulation style control of a module output.
    
A Pulse Width Modulated (PWM) output resource is an output that is controlled using a frequency and duty cycle.
Such drivers are often used to position control devices such as DC motors and solenoids through the manipulation
of duty cycle, and to a lesser extent, frequency. Pulse width modulated control generally involves varying the
amount of "ON" time, which is controlled through the Duty Cycle attribute. This behaviour is not intended for
frequency modulation. */

#ifndef __RESOURCE_PWM_H
#define __RESOURCE_PWM_H

/*----- INCLUDES ------------------------------------------------------------------------------------------*/
#include <typedefn.h>
#include <resource.h>
#include <NativeError.h>

/*----- DEFINES -------------------------------------------------------------------------------------------*/
/*! \brief Defines that value for 100% dutycycle. */
#define FULL_SCALE_DUTYCYCLE 4096L
/*! \brief Defines the frequency scaling applied to frequency values */
#define FREQUENCY_API_SCALING 100L

/*----- TYPEDEFS ------------------------------------------------------------------------------------------*/
#pragma pack(1)

/*! \brief Describes the operating frequency range of the device. Use the 
           S_PWMCreateResourceAttributes::u4MinFrequency in place of this attribute. */
typedef enum
{
    PWM_LF = 0,     /*!< Low Frequency [1.2Hz minimum] */
    PWM_MF = 1,     /*!< Medium Frequency [150Hz minimum] */
    PWM_HF = 2,     /*!< High Frequency [300Hz minimum] */
} E_PWMFreqMode;

/*! \brief Describes possible driving modes of the device, See \ref pwmdrivemode. Use the 
           S_PWMResourceAttributes::eDriveMode in place of this attribute. */
typedef enum
{
    PWM_DRIVE_NORMAL = 0,     /*!< Default, and on H-Bridge Normal, High Side On, Low Side PWM */
    PWM_DRIVE_BRAKING,        /*!< Braking mode, One Low Side on, other Low Side PWM, when duty +-100% both lowside on */
} E_PWMDriveMode;

/*! \brief Enumeration describes the set of mask definitions that are used to identify the valid PWM
           output attributes in the S_PWMResourceAttributes and S_PWMCreateResourceAttributes data structures.

Each mask definition applies to a particular member of one of the data structures.
\code
    ...
    S_PWMResourceAttributes AttribsObj;

    // Going to provide values for the resource condition and report condition so include in the mask
    AttribsObj.uValidAttributesMask = USE_PWM_DUTYCYCLE;
    AttribsObj.s2DutyCycle = (50 * FULL_SCALE_DUTYCYCLE) / 100L;
    // The remainder of the data structure can be left undefined since the uValidAttributesMask
    //   indicates that the members are not valid
    ... \endcode */
typedef enum
{
/*! Selects S_PWMResourceAttributes::s2DutyCycle \n 
    Boolean S_PWMCreateResourceAttributes if set during create and if \ref USE_PWM_CHILD 
    is used, then child PWM has indipendently controlled duty cycle.  By default Child PWMs have the same 
    duty cycle as \ref USE_PWM_PARENT parent PWM. */
    USE_PWM_DUTYCYCLE         = 0x0001, /* DO NOT CHANGE - Linked to USE_CJ125_LSU_PWM_FREQUENCY */
/*! Selects S_PWMResourceAttributes::u4Frequency */
    USE_PWM_FREQUENCY         = 0x0002, /* DO NOT CHANGE - Linked to USE_CJ125_LSU_PWM_DUTYCYCLE */
/*! Selects S_PWMResourceAttributes::eResourceCondition */
    USE_PWM_CONDITION         = 0x0004, /* DO NOT CHANGE - Linked to USE_CJ125_LSU_CONDITION */
/*! Selects S_PWMResourceAttributes::eResourceDiagCondition */
    USE_PWM_DIAG_CONDITION    = 0x0008, /* DO NOT CHANGE - Linked to USE_CJ125_PWM_DYNAMIC_RESERVED1 */
    USE_PWM_DYNAMIC_RESERVED2 = 0x0010, /* DO NOT CHANGE - Linked to USE_CJ125_PWM_DYNAMIC_RESERVED2 */
    USE_PWM_DYNAMIC_RESERVED3 = 0x0020, /* DO NOT CHANGE - Linked to USE_CJ125_PWM_DYNAMIC_RESERVED3 */
/*! Selects S_PWMCreateResourceAttributes::DynamicObj */
    USE_PWM_DYNAMIC_ON_CREATE = 0x0080,
/*! Selects S_PWMCreateResourceAttributes::eFreqMode */
    USE_PWM_FREQ_MODE         = 0x0100,
/*! Selects S_PWMCreateResourceAttributes::pfDiagCback */
    USE_PWM_DIAG_REPORT       = 0x0200,
/*! Selects S_PWMCreateResourceAttributes::u4MinFrequency */
    USE_PWM_MIN_FREQUENCY     = 0x0400,
/*! Select S_PWMCreateResourceAttributes::ePeakMode */
    USE_PWM_PEAK_DRIVER_MODE  = 0x0800,
/*! Select S_PWMResourceAttributes::uPeakTime */
    USE_PWM_PEAK_TIME         = 0x1000,
/*! Select S_PWMResourceAttributes::sPhaseDuty \n 
    LEGACY Select S_PWMCreateResourceAttributes::eSlaveRes  */
    USE_PWM_PHASE             = 0x2000,
/*! Boolean S_PWMCreateResourceAttributes, when set informs that this PWM 
    is to be of Synchronous PWM type, and with 0 or more Children (Synchronised child PWMs) */
    USE_PWM_PARENT            = 0x4000,
/*! Select S_PWMCreateResourceAttributes::eParentRes */
    USE_PWM_CHILD             = 0x8000,
/*! Select S_PWMResourceAttributes::eDriveMode */
    USE_PWM_DRIVE_MODE        = 0x00010000,
/*!< Selects S_PWMCreateResourceAttributes::eDriverMode */
    USE_PWM_DRIVER_MODE       = 0x00020000,        

/* IF THIS TYPE EXCEEDS 0x80000000 THEN ALTER THE TYPE OF THE uValidAttributesMask MEMBER(S) ACCORDINGLY */

} E_PWMAttributeMask;

typedef uint4 PWMAttributesMask_U;

/*! Enumeration defines the available PWM peak control modes */
typedef enum
{
/*! The PWM driver will operate in its high current mode when such a mode is supported by the hardware */
    PWM_PEAK_HIGH_CURRENT,
/*! The PWM driver will operate in its low current mode when such a mode is supported by the hardware */
    PWM_PEAK_LOW_CURRENT,
/*! The PWM driver will operate in a variable mode where the time spent in peak (the higher current mode)
    is defined with the S_PWMResourceAttributes::u2PeakTime attribute. This is a useful mode when driving
    the peak/hold injectors that are offered by some Woodward modules. This mode should not be used when
    not required because it does require some additional processing to support it. */
    PWM_PEAK_VARIABLE
} E_PWMPeakMode;
    
/*! \brief A PWM output resource's diagnostic information data structure.

     A reference to an instance of this object is supplied when the diagnostic notification pointer described
     by \ref PWMDiagCbackFuncPtrType is executed. Also see CreateResourceBEHAVIOUR_PWM() and
     \ref pwmdiagnostics. */
typedef struct
{
/*! Identifes the resource that generated this diagnostic report instance */
    E_ModuleResource eOwningResource;
/*! The status of the resource identified by S_PWMDiagInfo::eOwningResource. Often this state
    provides indeterminate information. See \ref pwmdiagnosticprinciples for further information on this */
    E_ResourceDiagStatus eDiagStatus;
} S_PWMDiagInfo;

typedef S_PWMDiagInfo const* S_PWMDiagInfoPtr;

/*! \brief Function pointer type that defines the prototype of the diagnostic notification function.

    The framework will call this function periodically, providing the application with diagnostic information
    for the assigned output resource.
    
    The \p in_uAppDataSentOnNotify is application data that was supplied to the framework via the
    S_PWMCreateResourceAttributes::uDiagCbackUserData when the callback function was defined. The function is
    defined as part of the CreateResourceBEHAVIOUR_PWM() call. See \ref howtopwmdiagnostics for an example. */
typedef void (*PWMDiagCbackFuncPtrType)(S_PWMDiagInfo const*,NativePtrSizedInt_U in_uAppDataSentOnNotify);

/*! \brief This data structure describes all of the PWM output resource's runtime configuration attributes.

    The attributes are altered through the use of SetResourceAttributesBEHAVIOUR_PWM(). The data
    structure does not need to be completely filled inorder to be used. The \b uValidAttributesMask is a bit
    field member that is used to identify which attributes are valid. Each attribute is identified with a
    separate bit mask that is logic-ORed into the a mask when an attribute is to be used.
    \code
    ...
    S_PWMResourceAttributes PWMObj;

    // Only going to set the Duty Cycle, Frequency and resource condition members
    PWMObj.uValidAttributesMask = USE_PWM_FREQUENCY | USE_PWM_DUTYCYCLE | USE_PWM_CONDITION;  \endcode */    
typedef struct
{
/*! Logic-OR the attributes [\ref USE_PWM_FREQUENCY, \ref USE_PWM_DUTYCYCLE, \ref USE_PWM_CONDITION, and
    \ref USE_PWM_DIAG_CONDITION ] that are valid for this this instance of the data structure.

    \code
    ...
    S_PWMResourceAttributes PWMObj;

    // Only going to set the Duty Cycle, and Frequency members
    PWMObj.uValidAttributesMask = USE_PWM_FREQUENCY | USE_PWM_DUTYCYCLE;
    PWMObj.s2DutyCycle = (10 * FULL_SCALE_DUTYCYCLE) / 100;
    PWMObj.u4Frequency = 1000 * FREQUENCY_API_SCALING;
    // The rest of the data structure can remain uninitialised because the framework will ignore it \endcode */    
    PWMAttributesMask_U uValidAttributesMask;
/*! The condition of the resource. A disabled resource remains in the safest state, which is OFF, regardless
    of what the other runtime attributes have been set to. Diagnostic reports are also blocked when a resource
    is disabled. Use the \ref USE_PWM_CONDITION mask to select this attribute. The value of this attribute upon
    resource creation is \ref RES_DISABLED. */
    E_ResourceCond eResourceCondition;
/*! The condition of the resource's diagnostic callback. A disabled callback will not execute, regardless of
    the observed condition. Disabling the resource will also disable the callback, even if this attribute is
    set. Use the \ref USE_PWM_DIAG_CONDITION to enable this attribute. The value of this attribute upon resource
    creation is \ref RES_ENABLED. */
    E_ResourceCond eResourceDiagCondition;
/*! Defines the percentage of the pulse-width period that the output should be active or "ON". Has units of percentage
    where 100% is defined by \ref FULL_SCALE_DUTYCYCLE. Select this attribute with the \ref USE_PWM_DUTYCYCLE bit mask.
    
    Also see \ref pwmdutyandfreq */
    sint2 s2DutyCycle;
/*! Defines the frequency in Hertz, which are internally scaled by \ref FREQUENCY_API_SCALING. Thus FREQUENCY_API_SCALING==1Hz.
    Select this attribute with the \ref USE_PWM_FREQUENCY bit mask.

    Also see \ref pwmdutyandfreq */
    uint4 u4Frequency;
/*! The peak time for use when the \ref PWM_PEAK_VARIABLE mode is in use. Select with the 
    \ref USE_PWM_PEAK_TIME attribute mask. */
    uint2 uPeakTime;
/*! The phase of the child (or LEGACY "slave") PWM. Select with the \ref USE_PWM_PHASE attribute mask. Describes the percentage of the period
    that the child channel is delayed from the parent channel. The child and parent channel are aligned if the value is 0%
    while a value of 50% indicates that the child is delayed by half the period. Has the same units as the
    S_PWMResourceAttributes::s2DutyCycle attribute. */
    sint2 sPhaseDuty;

/*! An H-Bridge can be driven in various modes. See \ref pwmdrivemode. 
    This attribute is selected with the \ref USE_PWM_DRIVE_MODE attribute. */
    E_PWMDriveMode eDriveMode;

} S_PWMResourceAttributes;

typedef S_PWMResourceAttributes const* S_PWMResourceAttributesPtr;

/*! \brief This data structure describes the creation attributes for a PWM output resource

    Included within the structure is the \p DynamicObj which represents the initial states for the resource's
    dynamic attributes. This data structure is referenced when the resource is created via the
    CreateResourceBEHAVIOUR_PWM() function and \ref USE_PWM_DYNAMIC_ON_CREATE is included in the
    S_PWMCreateResourceAttributes::uValidAttributesMask member.
    
    \code
    ...
    S_PWMCreateResourceAttributes PWMCreateObj;

    // Will use DynamicObj and the min frequency
    PWMCreateObj.uValidAttributesMask = USE_PWM_DYNAMIC_ON_CREATE | USE_PWM_MIN_FREQUENCY;
    PWMCreateObj.u4MinFrequency = 100 * FREQUENCY_API_SCALING;
    // Only going to set the Duty Cycle, and Frequency members
    PWMCreateObj.DynamicObj.uValidAttributesMask = USE_PWM_FREQUENCY | USE_PWM_DUTYCYCLE;
    PWMCreateObj.DynamicObj.s2DutyCycle = (10 * FULL_SCALE_DUTYCYCLE) / 100;
    PWMCreateObj.DynamicObj.u4Frequency = 1000 * FREQUENCY_API_SCALING;
    PWMCreateObj.DynamicObj.eResourceCondition = RES_ENABLED;
    // The rest of the data structure can remain uninitialised because the framework will ignore it \endcode 
    
    For an example of Synchronised PWMs see \ref syncpwmsample and \ref sychronisedpwm */
typedef struct
{
/*! Logic-OR the attributes [\ref USE_PWM_DYNAMIC_ON_CREATE, \ref USE_PWM_DIAG_REPORT, \ref USE_PWM_FREQ_MODE,
    and \ref USE_PWM_MIN_FREQUENCY] that are valid for this this instance of the data structure.

    \code
    ...
    S_PWMCreateResourceAttributes PWMCreateObj;

    // Will use DynamicObj and the min frequency
    PWMCreateObj.uValidAttributesMask = USE_PWM_DYNAMIC_ON_CREATE | USE_PWM_MIN_FREQUENCY;
    PWMCreateObj.u4MinFrequency = 100 * FREQUENCY_API_SCALING;
    // Only going to set the Duty Cycle, and Frequency members
    PWMCreateObj.DynamicObj.uValidAttributesMask = USE_PWM_FREQUENCY | USE_PWM_DUTYCYCLE;
    ... \endcode */
    PWMAttributesMask_U uValidAttributesMask;
/*! Defines the minimum frequency that the output is expected to operate at via an enumeration. See \ref pwmfreqmode
    for the use of this attribute. Select with the \ref USE_PWM_FREQ_MODE bit mask. This attribute is for legacy
    support only. The  S_PWMCreateResourceAttributes::u4MinFrequency member provides the same and more functionality.
    If undefined this attribute is set to \ref PWM_LF. */
    E_PWMFreqMode eFreqMode;
/*! The diagnostic notification function that should be used by the framework to notify the application
    of the created resource's diagnostic state. This function will be executed periodically by the framework.
    Select this attribute with the \ref USE_PWM_DIAG_REPORT bit mask. If not selected the default value
    of \c NULL shall be applied. */
    PWMDiagCbackFuncPtrType pfDiagCback;
/*! Application data that will be supplied as a parameter of the diagnostic notification callback function.
    Its type has been sized to allow a pointer to be stored in this parameter. */
    NativePtrSizedInt_U uDiagCbackUserData;
/*! The minimum frequency that this application requires this resource to operate at. See \ref pwmfreqmode for
    the usage of this attribute.
    
    This attribute enhances the functionality offered by the S_PWMCreateResourceAttributes::eFreqMode attribute
    and will be used in preference to it when selected via the \ref USE_PWM_MIN_FREQUENCY bit mask. If not selected
    then the framework will use the value of the S_PWMCreateResourceAttributes::eFreqMode to determine the minimum
    frequency expected and if neither are selected then it will use this attribute's default value. */
    uint4 u4MinFrequency;
/*! Initial values of the runtime attributes, which can be later altered through a call to
    SetResourceAttributesBEHAVIOUR_PWM(). Select with the \ref USE_PWM_DYNAMIC_ON_CREATE bit mask */
    S_PWMResourceAttributes DynamicObj;
/*! Defines the style of peak pin control required by this driver. The available options are always low current,
    always high current or peak mode control. In peak mode control the S_PWMResourceAttributes::u2PeakTime attribute
    is used to control the amount of time that the high current mode (peak mode) is enabled for. Select this attribute
    with the USE_PWM_PEAK_DRIVER_MODE mask. If not defined then the \ref PWM_PEAK_HIGH_CURRENT mode is assumed. */
    E_PWMPeakMode ePeakMode;
/*! LEGACY Set to a value when a synchronised slave channel is to be associated with the resource. Selected with the 
    \ref USE_PWM_PHASE, this attribute defaults to no slave resource. A slave will emulate the behaviour of the
    primary channel excepting that it's phase may be tuned via the S_PWMResourceAttributes::sPhaseDuty attribute */
    E_ModuleResource eSlaveRes;
/*! Set to a parent resource value when defined as a synchronised child channel. Selected with the 
    \ref USE_PWM_CHILD, this attribute defaults to create standard PWM. A child is sychronised with parent channel
    in terms of enable condition, frequency and optionally duty cycle. See \ref USE_PWM_DUTYCYCLE */
    E_ModuleResource eParentRes;

/*! Some drivers have the facility to operate in more than one mode. This attribute allows the mode to be selected.
    Modes include a low side driver and push pull driver. Selected with \ref USE_PWM_DRIVER_MODE, this attribute
    defaults to \ref DRIVER_LOW_SIDE in situations where mixed mode operation is supported or to the appropriate mode
    of the driver hardware when mixed mode operation is not supported. NOTE: DONT CONFUSE WITH \ref eDriveMode */
    E_DriverMode eDriverMode;

} S_PWMCreateResourceAttributes;

typedef S_PWMCreateResourceAttributes const* S_PWMCreateResourceAttributesPtr;

#pragma pack()
/*----- EXTERNALS -----------------------------------------------------------------------------------------*/

/*----- PROTOTYPES ----------------------------------------------------------------------------------------*/
NativeError_S GetPWMResourceCurrent(E_ModuleResource in_eID, sint2* out_ps2CurrentInMilliAmp);
NativeError_S SetPWMResourceFrequency(E_ModuleResource in_eID, uint4 in_u4Frequency);
NativeError_S SetPWMResourceDutyCycle(E_ModuleResource in_eID, sint2 in_sDutyCycle);
NativeError_S CreateResourceBEHAVIOUR_PWM(E_ModuleResource, S_PWMCreateResourceAttributes const*);
NativeError_S DestroyResourceBEHAVIOUR_PWM(E_ModuleResource in_eResource);
NativeError_S SetResourceAttributesBEHAVIOUR_PWM(E_ModuleResource, S_PWMResourceAttributes const*);

#endif /* __RESOURCE_PWM_H */

/*----- END OF FILE ---------------------------------------------------------------------------------------*/
