/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   Frequency Input Resource Framework API Header File
::   Copyright   :   (C)2002-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file Resource_FreqIn.h
    \brief Framework's Frequency Input resource management API

    The framework supports frequency input resources, which are described by the BEHAVIOUR_FREQIN behaviour.
    A frequency input is capable of measuring the frequency of an input pulse stream. The accuracy and range
    of the frequency input is defined by the virtual resource that is mapped to that input. Frequency can be
    measured from either edge, the edge being selected during resource creation. The timeliness of the 
    detection of zero edges is defined when the resource is created. Different detection methods place 
    differing execution burdens on the Framework.

    Observing the pulsewidth of a signal is also possible on a frequency inupt. This attribute is optional as
    it places more execution burden on the Framework which would be pointless to waste if pulsewidth is not
    of interest. The resource is configured to allow pulsewidth to be determined as part of the
    CreateResourceBEHAVIOUR_FREQIN() call.
*/
#ifndef __RESOURCE_FREQIN_H
#define __RESOURCE_FREQIN_H

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

/*----- DEFINES -------------------------------------------------------------------------------------------*/

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

/*! \brief Describe which edge of the input signal is used by the framework as the synchronous edge. 

    Period measurement, and thus frequency mesaurement, is relative to this edge. The edge is 
    relative to the module's input. Any inversion by hardware is automatcially taken into account
    by the framework. */
/* Name: E_FreqInEdgeDetect ClassID:ENUMDEC EnumDflt:"Illegal Setting" */
typedef enum
{
/*! Rising edge at the module's input is detected. */
    FREQ_IN_RISE_EDGE_DETECT,   /* EnumTxt:"Detect Rising Edge" */
/*! Falling edge at the module's input is detected. */
    FREQ_IN_FALL_EDGE_DETECT    /* EnumTxt:"Detect Falling Edge" */
} E_FreqInEdgeDetect;

/* Name: E_FreqInNotifyMode ClassID:ENUMDEC EnumDflt:"Illegal Setting" */
typedef enum
{
    FREQ_IN_NOTIFY_SYNCEDGE_NORMAL = 0, /* EnumTxt:"Notify if Period data available, and freq can be reported" */
    FREQ_IN_NOTIFY_RISING,              /* EnumTxt:"Notify on rising edge always" */
    FREQ_IN_NOTIFY_FALLING,             /* EnumTxt:"Notify on falling edge always" */
    FREQ_IN_NOTIFY_BOTH,                /* EnumTxt:"Notify on all edges" */
} E_FreqInEdgeNotify;

/*! \brief Describes the possible alias protection options available

 Alias protection is a characteristic that protects low frequency inputs from indicating the incorrect frequency when
 the frequency is very near the low threshold. It places execution burden upon the Framework because each edge results
 in the servicing of an interrupt. It \b should \b not be employed on inputs that consistently sit above the low
 frequency threshold under normal operation. The low frequency threshold is set at approximately 1.2 Hz for MPC5xx
 based modules.

 Alias protection will provide guaranteed uniform frequency response for all frequencies between 0 Hz and 39000 Hz.
 Inputs without alias protection may report incorrectly when they first start up, when they stop and while their
 frequency is near the low frequency threshold. */
/* Name: E_FreqInAliasProtectMode ClassID:ENUMDEC EnumDflt:"Illegal Setting" */
typedef enum
{
/*! No alias protection */
    FREQ_IN_NO_ALIAS_PROTECT = 0,   /* EnumTxt:"No Alias Protect" */
/*! Use Alias protection */ 
    FREQ_IN_USE_ALIAS_PROTECT = 1   /* EnumTxt:"Use Alias Protect" */
} E_FreqInAliasProtectMode;

/*! Describes the possible frequency input resolution options available.

    The granularity of the observed frequency is determined in part by hardware. Some module hardware has
    some control over the free running clock that is used to obtain the period measurement. Use the higher
    frequency setting for those inputs that are known to service higher frequency input sources, like a MAF
    for instance, to get better granularity. The threshold frequency where aliasing will begin to occur
    increases as the frequency range is increased. */

/* Name: E_FreqInFrequencyRange ClassID:ENUMDEC EnumDflt:"Illegal Setting"  */
typedef enum
{
/*! Best granularity at lower frequencies. Sacrifices resolution at higher frequencies to ensure
    the input is able to measure very low frequency values. */
    FREQ_IN_LOW_FREQUENCY,    /* EnumTxt:"Low Frequency Range" */
/*! Sacrfices low frequency measurement to allow high frequencies to measured with reasonable resolution */
    FREQ_IN_HIGH_FREQUENCY    /* EnumTxt:"High Frequency Range" */
} E_FreqInFrequencyRange;

/*! \brief Describes the hardware processing interface options available

Some resources support multiple hardware interfaces that can be selected dynamically within software. Typically
there is the choice between a standard digital input or a Variable Reluctance (VR) type interface. */

/* Name: E_FreqInSignalInterface ClassID:ENUMDEC EnumDflt:"Illegal"  */
typedef enum
{
/*! Use a standard digital input */
    FREQ_IN_DG_INPUT = 0,                    /* EnumTxt:"DG Input"   */
/*! Use a VR signal interface */
    FREQ_IN_VR_INPUT = 1                     /* EnumTxt:"VR Input"   */
} E_FreqInSignalInterface;

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

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

    // Going to provide values for the resource condition and report condition so include in the mask
    AttribsObj.uValidAttributesMask = USE_FREQIN_CONDITION;
    AttribsObj.eResourceCondition = RES_ENABLED;
    // The remainder of the data structure can be left undefined since the uValidAttributesMask
    //   indicates that the members are not valid
    ... \endcode */
typedef enum
{
    USE_FREQIN_CONDITION = 0x0001,            /*!< Selects S_FreqInResourceAttributes::eResourceCondition */
    USE_FREQIN_EDGE = 0x0002,                 /*!< Selects S_FreqInCreateResourceAttributes::eEdgeToDetect */
    USE_FREQIN_ALIAS = 0x0004,                /*!< Selects S_FreqInCreateResourceAttributes::eAliasProtectionMode */
    USE_FREQIN_FREQ_MODE = 0x0008,            /*!< Selects S_FreqInCreateResourceAttributes::eFrequencyRange */
    USE_FREQIN_SIGNAL = 0x0010,               /*!< Selects S_FreqInCreateResourceAttributes::eSignalInterface */
    USE_FREQIN_DYNAMIC_ON_CREATE = 0x0020,    /*!< Selects S_FreqInCreateResourceAttributes::DynamicObj */
    USE_FREQIN_DETECT_THRESH = 0x0040,        /*!< Selects S_FreqInCreateResourceAttributes::eDetectThresh */
    USE_FREQIN_MASK_BAD_FREQ = 0x0080,        /*!< Selects S_FreqInResourceAttributes::eMaskBadFreqCond */

/*!< Selects S_FreqInGetResourceAttributes::sPulseWidthDuty when used in conjunction with the member
     S_FreqInResourceAttributes::uValidAttributesMask. This mask value is also used to inform the Framework
     that pulse width measurement is required. This is achieved by including the mask in the member
     S_FreqInCreateResourceAttributes::uValidAttributesMask during resource creation. By default pulse width
     measurement is not supported because of the extra execution burden that it may places upon the Framework.
     For example a MDASM based microprocessor resource will require 1% of execution to service the pulse width
     capability on a 1kHz input signal. This execution would be wasted if the pulse width attribute was not
     actually required. */
    USE_FREQIN_PULSEWIDTH = 0x0100,           

    USE_FREQIN_FREQUENCY = 0x0200,            /*!< Selects S_FreqInGetResourceAttributes::uFrequency */
    USE_FREQIN_PERIOD = 0x0400,               /*!< Selects S_FreqInGetResourceAttributes::uPeriod */

    USE_FREQIN_NOTIFY = 0x0800,               /*!< Selects S_FreqInCreateResourceAttributes::pfOnEdgeNotify */
    USE_FREQIN_NOTIFY_SAMPLES = 0x1000,       /*!< Selects S_FreqInResourceAttributes::uEdgeNotifySamples and
                                                   S_FreqInCreateResourceAttributes::uMaxEdgeNotifySamples */
	USE_FREQIN_PINSTATE = 0x2000, 				  /*!< Selects S_FreqInResourceAttributes::uPinState */
	USE_FREQIN_NOTIFY_MODE = 0x4000, 		  /*!< Selects S_FreqInCreateResourceAttributes::eEdgeNotifyMode to 
												configure when notifications are required */
/* IF THIS TYPE EXCEEDS 0x8000 THEN ALTER THE TYPE OF THE FreqInValidAttributesMask_U ACCORDINGLY */

} E_FreqInAttributesMask;

/*! Unsigned integer type of sufficient size to hold the attribute masks for a frequency input described by \ref E_FreqInAttributesMask */
typedef uint2 FreqInValidAttributesMask_U;

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

    The attributes are altered through the use of SetResourceAttributesBEHAVIOUR_FREQIN(). 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_FreqInResourceAttributes FreqInObj;

    // Going to affect the eResourceCondition member and the condition 
    FreqInObj.uValidAttributesMask = USE_FREQIN_CONDITION;  \endcode */    
typedef struct
{
/*! Mask that defines which attributes within this structure are valid. Each dynamic attribute is assigned
    a flag which should be set by performing a logical-OR on this member. Supported attribute flags are 
    [\ref USE_FREQIN_CONDITION, USE_FREQIN_MASK_BAD_FREQ ].

    \code
    ...
    S_FreqInResourceAttributes FreqInObj;

    // Going to affect the eResourceCondition member and the condition 
    FreqInObj.uValidAttributesMask = USE_FREQIN_CONDITION;  \endcode */    
    FreqInValidAttributesMask_U uValidAttributesMask;
/*! The condition (whether the resource is Enabled or not). Select by logic-ORing the mask \ref USE_FREQIN_CONDITION
    into S_FreqInResourceAttributes::uValidAttributesMask. The framework will not observe frequency while the condition
    of a frequency input resource is \ref RES_DISABLED. The default condition upon creation is \ref RES_DISABLED. */
    E_ResourceCond eResourceCondition;

/*! Condition defines whether the framework should employ what ever data it has at its dispoasal to detect and mask
    off bad frequency measurements. For example, a noise glitch that occurs near another edge can result in a very
    high frequency that badly affect a weighted average. Enabling this attribute may allow the framework to detect
    such a condition and mask it from the application. Defaults to \ref RES_ENABLED upon resource creation. Select
    this attribute with the \ref USE_FREQIN_MASK_BAD_FREQ mask. */
    E_ResourceCond eMaskBadFreqCond;

/*! Defines the number of samples to be acquired by the Framework before a report is issued. This will be clipped
    to the value S_FreqInCreateResourceAttributes::uMaxEdgeNotifySamples that was set during resource creation */
    uint1 uEdgeNotifySamples;
} S_FreqInResourceAttributes;

typedef S_FreqInResourceAttributes const* S_FreqInResourceAttributesPtr;

/*! \brief  Frequency input attributes data structure
*/
typedef struct
{
/*! Mask that defines which attributes within this structure are valid. Each attribute is assigned
    a flag which should be set by performing a logical-OR on this member. Supported attribute flags are 
    [\ref USE_FREQIN_PULSEWIDTH, and \ref USE_FREQIN_FREQUENCY]
    \code
    ...
    S_FreqInGetResourceAttributes AttribsObj;

    // Going to provide values for the detection edge so include in the mask
    AttribsObj.uValidAttributesMask = USE_FREQIN_PULSEWIDTH | USE_FREQIN_FREQUENCY;
    ... \endcode */
    FreqInValidAttributesMask_U uValidAttributesMask;

/*! The last observed dutycycle. The dutycycle describes the elapsed time between the occurrence of the
    non-synchronous edge and the synchronous edge. The synchronous edge is configured during the creation
    of the resource via the S_FreqInCreateResourceAttributes::eEdgeToDetect member. 4096 represents 100%.
    Use the \ref USE_FREQIN_PULSEWIDTH mask to select this attribute */
    sint2 sDutyCycle;

/*! The last observed frequency. It has units of 1/100th Hz. Select this attribute with the
    \ref USE_FREQIN_FREQUENCY */
    uint4 uFrequency;

/*! The last observed period in microseconds. It is the inverse of S_FreqInGetResourceAttributes::uFrequency.
    Select this attribute with the \ref USE_FREQIN_PERIOD */
    uint4 uPeriod;

/*! Period between synchronous edge and non-synchronous edge.  If zero pulse is being measured or 
    Was too long to be measured. Use the \ref USE_FREQIN_PULSEWIDTH mask to select this attribute */
	uint4 uPulsePeriod;

/*! State of Pin, Use the \ref USE_FREQIN_PINSTATE */
	E_ResourcePinState uPinState;

} S_FreqInGetResourceAttributes;

/*! \brief List of possible report status values.

           The status is supplied as a parameter of the notification function that executes (when requested)
           when an input edge is observed. The notification function S_FreqInCreateResourceAttributes::pfOnEdgeNotify
           is defined during creation. */
typedef enum
{
    FREQIN_STATUS_OK,           /*!< The report was issued and all is okay */
    FREQIN_STATUS_MISSED,       /*!< A requested report was missed because of processor loading versus the frequency
                                     of the signal being monitored. */
    FREQIN_STATUS_NOT_COHERENT, /*!< The data within the report is known to not be coherent. */
} E_FreqInReportStatus;

/*! \brief Notification function definition that executes on the synchronous edge once enabled.

    The second parameter describes an array of frequency input attributes. The number of elements in this array
    is defined by the in_uNumElementsInArray parameter. The data is coherent with the edge that resulted in this
    notification event executing.
    
    The in_eStatus parameter will report the status of this report. Reports could include that the information
    contained within the array is known to not be coherent (interrupt latency resulted in the data being missed)
    or to indicate that some edges were missed between when this report executed and when the last report
    executed.

    Context specific data that was supplied when the notification was created is contained within the pAppData
    parameter

    The in_eStatus parameter defines the status of the report. A value of \ref FREQIN_STATUS_OK indicates a good
    report. A value \ref FREQIN_STATUS_MISSED indicates that the vector in_pArr is itself coherent with the last
    observed edge, but that there were edges that occurred between this report and the last that were not captured.

    The returned value allows the application to define whether further notification events are required. Return zero
    if no further notifications are required until SetResourceAttributesBEHAVIOUR_FREQIN() is used to alter the
    S_FreqInResourceAttributes::uEdgeNotifySamples attribute. Any other value implies that further notificatio reports
    are required. The size of the return indicates how many edges need to be observed before the next report is issued.
    This value will be clipped against the maximum number of samples that was defined during creation of the resource.
*/
typedef NativeVar_U (*PFNFREQINEDGENOTIFY)(E_ModuleResource,
                                           S_FreqInGetResourceAttributes const* in_pArr,
                                           uint1 const in_uNumElementsInArray,
                                           E_FreqInReportStatus in_eStatus,
                                           void* pAppData);


/*! \brief  Attributes of the frequency input that are supplied when creating a frequency input resource.

The creation attribute structure contains creation specific attributes as well as a copy of the dynamic attributes.
The creation attributes are used to define characteristics of the behaviour that can not be changed once the resource
has been created. The resource would need to be destroyed before these characteristics could be altered again
(effectively allowing a Re-create).

Those creation attributes that are to have values other than the default need to be selected via the
S_FreqInCreateResourceAttributes::uValidAttributesMask member using the appropriate bit mask.

\code
    ...
    S_FreqInCreateResourceAttributes AttribsObj;

    // Going to provide values for the detection edge so include in the mask
    AttribsObj.uValidAttributesMask = USE_FREQIN_EDGE;
    AttribsObj.eEdgeToDetect = FREQ_IN_FALL_EDGE_DETECT;
    // The remainder of the data structure can be left undefined since the uValidAttributesMask
    //   indicates that the members are not valid
    ... \endcode
The dynamic attributes are supplied to allow an initial state to be applied to the behaviour once creation
has occurred. */
typedef struct
{
/*! Mask that defines which attributes within this structure are valid. Each dynamic attribute is assigned
    a flag which should be set by performing a logical-OR on this member. Supported attribute flags are 
    [\ref USE_FREQIN_EDGE, \ref USE_FREQIN_ALIAS, \ref USE_FREQIN_FREQ_MODE, \ref USE_FREQIN_SIGNAL,
     \ref USE_FREQIN_DYNAMIC_ON_CREATE, and \ref USE_FREQIN_PULSEWIDTH]
    \code
    ...
    S_FreqInCreateResourceAttributes AttribsObj;

    // Going to provide values for the detection edge so include in the mask
    AttribsObj.uValidAttributesMask = USE_FREQIN_EDGE;
    AttribsObj.eEdgeToDetect = FREQ_IN_FALL_EDGE_DETECT;
    // The remainder of the data structure can be left undefined since the uValidAttributesMask
    //   indicates that the members are not valid
    ... \endcode */
    FreqInValidAttributesMask_U uValidAttributesMask;
/*! Define what the synchronous edge of the input signal will be. Signal period, and thus Frequency, shall be measured
    with respect to this edge.  If not defined then \ref FREQ_IN_RISE_EDGE_DETECT is applied to this attribute. Select
    with the \ref USE_FREQIN_EDGE bit mask. */
    E_FreqInEdgeDetect eEdgeToDetect;
/*! Define whether alias protection is to be employed. If not defined then \ref FREQ_IN_NO_ALIAS_PROTECT is applied
    to this attribute. Select with the \ref USE_FREQIN_ALIAS bit mask.
     
    Alias protection is a characteristic that protects low frequency inputs from indicating the incorrect frequency
    when the frequency is very near the low threshold. It places execution burden upon the Framework because each 
    edge results in the servicing of an interrupt. It \b should \b not be employed on inputs that consistently sit
    above the low frequency threshold under normal operation. The low frequency threshold is set at approximately
    1.2 Hz for MPC5xx based modules.

    Alias protection will provide guaranteed uniform frequency response for all frequencies between 0 Hz and 39000 Hz.
    Inputs without alias protection may report incorrectly when they first start up, when they stop and while their 
    frequency is near the low frequency threshold. */
    E_FreqInAliasProtectMode eAliasProtectionMode;

/*! The granularity of the frequency input. If not defined then \ref FREQ_IN_LOW_FREQUENCY is applied to this attribute.
    Select with the \ref USE_FREQIN_FREQ_MODE bit mask.

    The granularity of the observed frequency is determined in part by hardware. Some module hardware has some control
    over the free running clock that is used to obtain the period measurement. Use the higher frequency setting for those
    inputs that are known to service higher frequency input sources, like a MAF for instance, to get better granularity.
    The threshold frequency where aliasing will begin to occur increases as the frequency range is increased. */
    E_FreqInFrequencyRange eFrequencyRange;
/*! Some resources support multiple hardware interfaces that can be selected dynamically within software. Typically
    there is the choice between a standard digital input or a Variable Reluctance (VR) type interface. This attribute
    define which signal interface should be used by the module hardware. If not defined then \ref FREQ_IN_DG_INPUT is
    is applied to this attribute. Select with the \ref USE_FREQIN_SIGNAL bit mask. */
    E_FreqInSignalInterface eSignalInterface;

/*! Structure that holds the initial values of the dynamic attributes that will be applied during creation.
    These can be subsequently changed with a call to SetResourceAttributesBEHAVIOUR_FREQIN(). Select this
    attribute with the \ref USE_FREQIN_DYNAMIC_ON_CREATE bit mask.  */
    S_FreqInResourceAttributes DynamicObj;

/*! Some inputs have runtime configurable hardware to manipulate how the threshold for edge detection is
    determined. This attribute allows this to be configured. The attribute is selected with the
    \ref USE_FREQIN_DETECT_THRESH bit mask and defaults to \ref THRESH_FIXED_HW when not selected. This attribute
    is ignored by those resources that do not support this functionality without erroring */
    E_DetectionThreshMode eDetectThresh;

/*! Notification function that will execute on an edge when enabled.

    This attribute is selected with the \ref USE_FREQIN_NOTIFY. The notification will not occur by defaulting
    to NULL when not selected */
    PFNFREQINEDGENOTIFY pfOnEdgeNotify;
/*! Pointer to application data that shall be supplied when the notification function
    S_FreqInCreateResourceAttributes::pfOnEdgeNotify executes */
    void* pOnEdgeNotifyData;

/*! Describes the maximum number of samples that may be acquired. The S_FreqInResourceAttributes::uEdgeNotifySamples
    member shall be clipped to this value. Select with the \ref USE_FREQIN_NOTIFY_SAMPLES bit mask. This member shall
    have a default value of 1 if not selected */
    uint1 uMaxEdgeNotifySamples;

/*! Use \ref USE_FREQIN_NOTIFY_MODE to select when notifications will occur */
	E_FreqInEdgeNotify eEdgeNotifyMode; 
} S_FreqInCreateResourceAttributes;

typedef S_FreqInCreateResourceAttributes const* S_FreqInCreateResourceAttributesPtr;

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

/*----- PROTOTYPES ----------------------------------------------------------------------------------------*/
/* Optimised calls that can be applied to certain attribute get/sets                                       */
NativeError_S GetFrequencyResourceFrequency(E_ModuleResource, uint4* out_puFreq);

NativeError_S CreateResourceBEHAVIOUR_FREQIN(E_ModuleResource, S_FreqInCreateResourceAttributes const*);
NativeError_S DestroyResourceBEHAVIOUR_FREQIN(E_ModuleResource);
NativeError_S SetResourceAttributesBEHAVIOUR_FREQIN(E_ModuleResource, S_FreqInResourceAttributes const*);
NativeError_S GetResourceAttributesBEHAVIOUR_FREQIN(E_ModuleResource, S_FreqInGetResourceAttributes*);

NativeError_S FrequencyInput_Period_Raw_Get32Bit(E_ModuleResource, uint4* const out_pRawPeriod, uint4* const out_pRawPulseWidth);
NativeError_S FrequencyInput_Period_Raw_Get16Bit(E_ModuleResource, uint2* const out_pRawPeriod, uint2* const out_pRawPulseWidth);

#endif /* __RESOURCE_FREQIN_H */

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