/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   Analog Resource Framework API Header File
::   Copyright   :   (C)2002-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file Resource_Analog.h
    \brief The \ref BEHAVIOUR_ANALOGIN provides the framework with the capability to sample input resources that
           feed a module's Analogue to Digital Converter (ADC) resources. See \ref continuousadcsample */
    
#ifndef __RESOURCE_ANALOG_H
#define __RESOURCE_ANALOG_H

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

/*----- DEFINES -------------------------------------------------------------------------------------------*/
/*! brief Divide by this value to convert a value of the \ref mVolt_U type into units of 1 Volt and multiply
          by this value to convert a voltage into one compatible with the \ref mVolt_U type. */
#define VOLT_SCALE          1000UL

/*! brief Divide by this value to convert a value of the \ref DegCelcius_U type into units of 1 degree Celcius
          and multiply by this value to convert a temperature into one compatible with the \ref DegCelcius_S
          type. */
#define TEMPERATURE_SCALE    10UL

#define MAX_NUM_TRIGGER_SAMPLES 2 /* Samples per slot */

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

/*! \brief Enumeration describes the set of mask definitions that are used to identify the valid analogue
           input attributes in the S_AnalogInAttributes and S_AnalogInCreateAttributes data structures.

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

    // Will use DynamicObj
    CreateObj.uValidAttributesMask = USE_ANALOG_DYNAMIC_ON_CREATE;
    CreateObj.DynamicObj.uValidAttributesMask = USE_ANALOG_CONDITION;
    CreateObj.DynamicObj.eResourceCondition = RES_ENABLED;
    // The rest of the data structure can remain uninitialised because the framework will ignore it \endcode */    
typedef enum
{
    USE_ANALOG_DEFAULTS          = 0x00,    /*!< S_AnalogHowToGet::uValidAttributesMask setting that
                                                 Configures system to get timemased value with S_AnalogHowToGet. 
                                                 This enum should not be used in combination with any of the 
                                                 others, as it will have no effect */
    USE_ANALOG_CONDITION         = 0x01,    /*!< Selects S_AnalogInAttributes::eResourceCondition */
    USE_ANALOG_DYNAMIC_ON_CREATE = 0x02,    /*!< Selects S_AnalogInCreateAttributes::DynamicObj */
    /*! Boolean in S_AnalogInCreateAttributes::uValidAttributesMask That Enables the use of the 
        alternative reference (ALTREF) on the QADC, where available. Can only be set on create. 
        See \ref altref */
    USE_ALTERNATE_REFERENCE      = 0x04,    
    USE_ANALOG_TRANSFORM         = 0x08,    /*!< Selects S_AnalogHowToGet::eTransformType */
    /*! Boolean in S_AnalogHowToGet::uValidAttributesMask that during GetResourceValueBEHAVIOUR_ANALOGIN() 
        Saves current uADCValue as the uZeroADC. */
    USE_ANALOG_SET_ZERO_ADC      = 0x10,    
    /*! Selects S_AnalogInCreateAttributes::eTriggerResource during CreateResourceBEHAVIOUR_ANALOG_TRIGGER() \n
        Selects S_AnalogHowToGet::eTriggerResource during GetResourceValueBEHAVIOUR_ANALOGIN() */
    USE_ANALOG_TRIGGER_RESOURCE  = 0x20,    
    USE_ANALOG_SLOTID            = 0x40,    /*!< Selects S_AnalogHowToGet::eSlotID  */   

/* IF THIS TYPE EXCEEDS 0x80 THEN ALTER THE TYPE OF THE uValidAttributesMask MEMBER ACCORDINGLY */

} E_AnalogAttributesMask;

/* Note if more E_AnalogAttributesMask are added greater than 0x80, then the typedef AnalogAttributesMask_U 
   Needs to increase in storage size from uint1 */ 
typedef uint1 AnalogAttributesMask_U;

/*! \brief Enumeration describes valid slot locations for \ref BEHAVIOUR_ANALOGIN data retrieval.  

\ref ANALOG_SLOT_AVG takes the average for that channel across all slots, as does \ref ANALOG_SLOT_DEFAULT.
If there is only one SLOT, then the unique sample value is retrieved.
    \code
    ...
    S_AnalogHowToGet HowToGetObj;
    S_AnalogResult AnalogResultObj;

    HowToGetObj.uValidAttributesMask = USE_ANALOG_TRIGGER_RESOURCE | USE_ANALOG_SLOTID | USE_ANALOG_TRANSFORM;
    HowToGetObj.eTriggerResource   = RES_ADCTRIG_A;
    HowToGetObj.eSlotID            = ANALOG_SLOT2;
    HowToGetObj.eTransformType     = ANALOG_AS_CURRENT;

    // RES_LSD1 Get the load current as sampled on Triggered Queue A, 2nd Slot, and convert value to current 
    GetResourceValueBEHAVIOUR_ANALOGIN(RES_LSD1, &HowToGetObj, &AnalogResultObj);
    u2LSD1TriggerValue   = AnalogResultObj.uADCValue;
    s2LSD1TriggerCurrent = AnalogResultObj.sMilliAmps;
    \endcode */    
typedef enum
{
    ANALOG_SLOT1,               /*!< Access slot #1 */
    ANALOG_SLOT2,               /*!< Access slot #2 */
    ANALOG_TRIGGER_NUM_SLOTS,   /*!< Total number of slots supported on trigger queues */
    ANALOG_SLOT_AVG = 0xff,     /*!< Default obtain average of all slots */
    ANALOG_SLOT_DEFAULT = 0xff, /*!< Default obtain average of all slots */
} E_SlotID;

/*! \brief Enumeration describes valid data unit Transformations for the ADC.  

Depending on hardware support, data can be retireved in different forms, from different hardware queues.
See \ref S_AnalogHowToGet for more detail.

    \code
    ...
    S_AnalogHowToGet HowToGetObj;
    S_AnalogResult AnalogResultObj;

    // RES_AN1M Get the value as sampled on Timebased Queue 
    GetResourceValueBEHAVIOUR_ANALOGIN(RES_AN1M, &HowToGetObj, &AnalogResultObj);
    u2AN1MValue   = AnalogResultObj.uADCValue;
    \endcode */    
typedef enum
{
    /*! By default all S_AnalogResult uADCValue is always available */
    ANALOG_AS_VALUE = 0,
    /*! Transform uADCValue to Voltage, store in S_AnalogResult uMilliVolts. See \ref voltagesample  */
    ANALOG_AS_VOLTAGE,
    /*! Transform uADCValue to Current, store in S_AnalogResult sMilliAmps, sign indicates 
        direction of current in Hbridge for example. See \ref currentsample */
    ANALOG_AS_CURRENT,
    /*! Transform uADCValue to Temperature, store in S_AnalogResult sDegsCelcius. See \ref temperaturesample */
    ANALOG_AS_TEMPERATURE,
} E_TransformType;


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

    The attributes are altered through the use of SetResourceAttributesBEHAVIOUR_ANALOGIN(). 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_AnalogInAttributes ADCObj;

    // Only going to set the condition member
    ADCObj.uValidAttributesMask = USE_ANALOG_CONDITION;  \endcode */

typedef struct
{
/*! Logic-OR the attributes [\ref USE_ANALOG_CONDITION] that are valid for this this instance of the data structure.
    The valid attributes are described by the \ref E_AnalogAttributesMask enumeration
    \code
    ...
    S_AnalogInAttributes ADCObj;

    // Only going to set the condition member
    ADCObj.uValidAttributesMask = USE_ANALOG_CONDITION;  \endcode */
    AnalogAttributesMask_U uValidAttributesMask;
/*! Set to RES_ENABLED to allow conversion to take place on this channel. \ref USE_ANALOG_CONDITION */
    E_ResourceCond eResourceCondition;
} S_AnalogInAttributes;

typedef S_AnalogInAttributes const* S_AnalogInAttributesPtr;

/*! \brief This data structure describes the creation attributes for an analog input 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_ANALOGIN() function and \ref USE_ANALOG_DYNAMIC_ON_CREATE is included in the
    S_AnalogInCreateAttributes::uValidAttributesMask member.
    
    \code
    ...
    S_AnalogInCreateAttributes CreateObj;

    // Will use DynamicObj from create
    CreateObj.uValidAttributesMask = USE_ANALOG_DYNAMIC_ON_CREATE;
    // Will use the condition attribute of the dynamic object
    CreateObj.DynamicObj.uValidAttributesMask = USE_ANALOG_CONDITION;
    CreateObj.DynamicObj.eResourceCondition = RES_ENABLED;
    // The rest of the data structure can remain uninitialised because the framework will ignore it \endcode */    
typedef struct
{
/*! Logic-OR the attributes [\ref USE_ANALOG_DYNAMIC_ON_CREATE] that are valid for this this instance of the data structure.
    The valid attributes are described by the \ref E_AnalogAttributesMask enumeration

    \code
    ...
    S_AnalogInCreateAttributes CreateObj;

    // Will use DynamicObj and the min frequency
    CreateObj.uValidAttributesMask = USE_ANALOG_DYNAMIC_ON_CREATE | USE_ANALOG_TRIGGER_RESOURCE;
    CreateObj.eTriggerResource     = RES_ADCTRIG_A; // Create on trigger queue A
    CreateObj.DynamicObj.uValidAttributesMask = USE_ANALOG_CONDITION;
    CreateObj.DynamicObj.eResourceCondition = RES_ENABLED;
    // The rest of the data structure can remain uninitialised because the framework will ignore it \endcode */    
    AnalogAttributesMask_U uValidAttributesMask;
/*! Initial values of the runtime attributes, which can be later altered through a call to
    SetResourceAttributesBEHAVIOUR_ANALOGIN(). Select with the \ref USE_ANALOG_DYNAMIC_ON_CREATE bit mask */
    S_AnalogInAttributes DynamicObj;
/*! Selects which trigger resource to use with CreateResourceBEHAVIOUR_ANALOG_TRIGGER(). 
    Select this attribute with the \ref USE_ANALOG_TRIGGER_RESOURCE mask. 
    This attribute is assumed to be  \ref RES_ADCTIME, (time based ADC Sampling) queue when not selected. */
    E_ModuleResource eTriggerResource;   
} S_AnalogInCreateAttributes;

typedef S_AnalogInCreateAttributes const* S_AnalogInCreateAttributesPtr;

/*! \brief This data structure describes How to Get the data for an analog input resource

Depending on hardware support, data can be retireved in different forms, from different hardware queues.
This structure tells \ref GetResourceValueBEHAVIOUR_ANALOGIN(), how to obtain the data.

\ref ANALOG_AS_VALUE and \ref ANALOG_AS_VOLTAGE are always supported.  
S_AnalogResult::uADCValue is obtained by default, and so \ref ANALOG_AS_VALUE is the default 
S_AnalogHowToGet::eTransformType.

    \code
    ...
    S_AnalogHowToGet HowToGetObj;
    S_AnalogResult AnalogResultObj;

    // RES_AN1M Get the value as sampled on Timebased Queue 
    GetResourceValueBEHAVIOUR_ANALOGIN(RES_AN1M, &HowToGetObj, &AnalogResultObj);
    u2AN1MValue   = AnalogResultObj.uADCValue;
    \endcode 

    \code
    ...
    S_AnalogHowToGet HowToGetObj;
    S_AnalogResult AnalogResultObj;

    HowToGetObj.uValidAttributesMask = USE_ANALOG_TRIGGER_RESOURCE | USE_ANALOG_SLOTID | USE_ANALOG_TRANSFORM;
    HowToGetObj.eTriggerResource   = RES_ADCTRIG_A;
    HowToGetObj.eSlotID            = ANALOG_SLOT2;
    HowToGetObj.eTransformType     = ANALOG_AS_CURRENT;

    // RES_LSD1 Get the load current as sampled on Triggered Queue A, 2nd Slot, and convert value to current 
    GetResourceValueBEHAVIOUR_ANALOGIN(RES_LSD1, &HowToGetObj, &AnalogResultObj);
    u2LSD1TriggerValue   = AnalogResultObj.uADCValue;
    s2LSD1TriggerCurrent = AnalogResultObj.sMilliAmps;
    \endcode */    
      
/*! Specify how and where to obtain ADC data from when using \ref BEHAVIOUR_ANALOGIN */
typedef struct
{
/*! Logic-OR the attributes that are valid for this this instance of the data structure. 
    see \ref S_AnalogInAttributes for valid attributes
*/
    AnalogAttributesMask_U uValidAttributesMask;
    /*! Selects which trigger resource to use with GetResourceValueBEHAVIOUR_ANALOGIN(). 
        Select this attribute with the \ref USE_ANALOG_TRIGGER_RESOURCE mask. 
        This attribute is assumed to be \ref RES_ADCTIME, the time based ADC Sampling queue when not selected. */
    E_ModuleResource       eTriggerResource;
    /*! Selects which Slot ID to use with GetResourceValueBEHAVIOUR_ANALOGIN(). 
        Select this attribute with the \ref USE_ANALOG_SLOTID mask. 
        This attribute is assumed to be \ref ANALOG_SLOT_AVG when not selected, and 
        calculates the average of all slots, or the single value if there is only one slot. */
    E_SlotID               eSlotID;
    /*! Selects which unit transformation to use with GetResourceValueBEHAVIOUR_ANALOGIN(). 
        Select this attribute with the \ref USE_ANALOG_TRANSFORM mask. 
        This attribute is assumed to be ANALOG_AS_VALUE when not selected. */
    E_TransformType        eTransformType; 
} S_AnalogHowToGet;

/*! brief Voltage unsigned integer type.

          Describes a voltage where 1 volt == 1000. Type defined to an unsigned integer type so that this type
          could be modified by the Framework developers to extend the range of this voltage. Currently has
          enough range to describe 65V */
typedef uint2 mVolt_U;

/*! brief Voltage unsigned integer type.

          Describes a voltage where 1 degree == 10 (TEMPERATURE_SCALE). Type defined to a signed integer type */ 
typedef sint2 DegCelcius_S;

/*! brief Voltage unsigned integer type.

          Describes a current where 1 Amp == 1000mA. Type defined to an signed integer, as in HBridges current
          can flow in either direction.*/
typedef sint2 mAmp_S;

/*! \brief This data structure describes Data structure in which ADC data is returned

Depending on hardware support, data can be retireved in different forms, \ref S_AnalogHowToGet describes
Which transform to apply if applicable. See \ref S_AnalogHowToGet for an example */
typedef struct
{
    /*! ADC Value transformed to mV, when used with S_AnalogHowToGet::uValidAttributesMask |= \ref USE_ANALOG_TRANSFORM, and \ref ANALOG_AS_VOLTAGE eTransformType  */
    mVolt_U      uMilliVolts;
    /*! ADC Value transformed to DegreesCelcius scaled, when used with S_AnalogHowToGet::uValidAttributesMask |= \ref USE_ANALOG_TRANSFORM, and \ref ANALOG_AS_TEMPERATURE eTransformType  */
    DegCelcius_S sDegsCelcius;
    /*! ADC Value transformed to mA, when used with S_AnalogHowToGet::uValidAttributesMask |= \ref USE_ANALOG_TRANSFORM, and \ref ANALOG_AS_CURRENT eTransformType  */
    mAmp_S       sMilliAmps;
    /*! Raw ADC value as sampled */
    NativeADC_U  uADCValue;
    /*! Used to return the ZeroADCValue thsi value is typically set for current sampling.  When the output driver 
    is off, the ADC value is read and stored as the Zero value.  When the Current transform is calculated, the 
    compensated ADC value used in the calculation is (uADCValue - uZeroADC) in order to remove any zero based offset.  */
    NativeADC_U  uZeroADCValue;
} S_AnalogResult;

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

/*----- PROTOTYPES ----------------------------------------------------------------------------------------*/

/* Single GetResourceValue method supports multiple data types */
NativeError_S GetResourceValueBEHAVIOUR_ANALOGIN(E_ModuleResource in_eADCResource, S_AnalogHowToGet const *in_pHowToGet, S_AnalogResult *out_pResult);

/* Legacy Get Value, Voltage and Temperature Methods */
NativeError_S GetAnalogResourceValue(E_ModuleResource, NativeADC_U* out_puValue);
NativeError_S GetAnalogResourceVoltage(E_ModuleResource, mVolt_U* out_pMilliVoltValue);
NativeError_S GetAnalogResourceTemperature(E_ModuleResource, DegCelcius_S* out_pScaledDegCelciusValue);

NativeError_S CreateResourceBEHAVIOUR_ANALOGIN(E_ModuleResource, S_AnalogInCreateAttributes const*);
NativeError_S DestroyResourceBEHAVIOUR_ANALOGIN(E_ModuleResource);
NativeError_S SetResourceAttributesBEHAVIOUR_ANALOGIN(E_ModuleResource, S_AnalogInAttributes const*);

#endif /* __RESOURCE_ANALOG_H */

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