/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   CAN Communications Resource Framework API Header File
::   Copyright   :   (C)2002-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file  Resource_CAN.h
 \brief The BEHAVIOUR_CAN behaviour exposes the framework's CAN bus interface behaviour. This behaviour allows
 CAN messages to be sent and received over a CAN bus. See also \ref whatisacanbuffer, \ref cantransmission and
 \ref canreceiptnotify */

#ifndef __RESOURCE_CAN_H
#define __RESOURCE_CAN_H

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

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

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

/*! \brief Enumeration describes the available TouCAN Hardware buffers. Some TouCAN devices in Woodward MPC565
    modules have more than the normal 16 TouCAN hardware buffers available to them */
typedef enum
{
    TOUCAN_BUFF0,   /*!< TouCAN Hardware Buffer, MBUFF0  */
    TOUCAN_BUFF1,   /*!< TouCAN Hardware Buffer, MBUFF1  */
    TOUCAN_BUFF2,   /*!< TouCAN Hardware Buffer, MBUFF2  */
    TOUCAN_BUFF3,   /*!< TouCAN Hardware Buffer, MBUFF3  */
    TOUCAN_BUFF4,   /*!< TouCAN Hardware Buffer, MBUFF4  */
    TOUCAN_BUFF5,   /*!< TouCAN Hardware Buffer, MBUFF5  */
    TOUCAN_BUFF6,   /*!< TouCAN Hardware Buffer, MBUFF6  */
    TOUCAN_BUFF7,   /*!< TouCAN Hardware Buffer, MBUFF7  */
    TOUCAN_BUFF8,   /*!< TouCAN Hardware Buffer, MBUFF8  */
    TOUCAN_BUFF9,   /*!< TouCAN Hardware Buffer, MBUFF9  */
    TOUCAN_BUFF10,  /*!< TouCAN Hardware Buffer, MBUFF10 */
    TOUCAN_BUFF11,  /*!< TouCAN Hardware Buffer, MBUFF11 */
    TOUCAN_BUFF12,  /*!< TouCAN Hardware Buffer, MBUFF12 */
    TOUCAN_BUFF13,  /*!< TouCAN Hardware Buffer, MBUFF13 */
    TOUCAN_BUFF14,  /*!< TouCAN Hardware Buffer, MBUFF14 */
    TOUCAN_BUFF15,  /*!< TouCAN Hardware Buffer, MBUFF15 */
    TOUCAN_BUFF16,  /*!< TouCAN Hardware Buffer, MBUFF0  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF17,  /*!< TouCAN Hardware Buffer, MBUFF1  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF18,  /*!< TouCAN Hardware Buffer, MBUFF2  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF19,  /*!< TouCAN Hardware Buffer, MBUFF3  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF20,  /*!< TouCAN Hardware Buffer, MBUFF4  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF21,  /*!< TouCAN Hardware Buffer, MBUFF5  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF22,  /*!< TouCAN Hardware Buffer, MBUFF6  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF23,  /*!< TouCAN Hardware Buffer, MBUFF7  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF24,  /*!< TouCAN Hardware Buffer, MBUFF8  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF25,  /*!< TouCAN Hardware Buffer, MBUFF9  TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF26,  /*!< TouCAN Hardware Buffer, MBUFF10 TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF27,  /*!< TouCAN Hardware Buffer, MBUFF11 TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF28,  /*!< TouCAN Hardware Buffer, MBUFF12 TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF29,  /*!< TouCAN Hardware Buffer, MBUFF13 TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF30,  /*!< TouCAN Hardware Buffer, MBUFF14 TouCAN C Only available on MPC565 Modules */
    TOUCAN_BUFF31,  /*!< TouCAN Hardware Buffer, MBUFF15 TouCAN C Only available on MPC565 Modules */
} E_TouCANBuffer;

typedef uint1 TouCANBufferHandle;

/*! \brief Enumeration describes recommended baud rates supported by the framework.

    When one of these settings is used the S_CANBusParams data structure is filled by the framework. The 
    S_CANBusParams can be overridden by using the \c CAN_BAUD_CUSTOM setting. */
typedef enum
{
/*! Use this value when the user is going to specifiy the baud rate directly by way of the \ref S_CANBusParams
    data structure. */
    CAN_BAUD_CUSTOM,
/*! 250 kBit/second */
    CAN_BAUD_250K,
/*! 50 kBit/second */
    CAN_BAUD_050K,
/*! 62.5 kBit/second */
    CAN_BAUD_062p5K,
/*! 83.3 kBit/second */
    CAN_BAUD_083p3K,
/*! 100 kBit/second */
    CAN_BAUD_100K,
/*! 125 kBit/second */
    CAN_BAUD_125K,
/*! 500 kBit/second */
    CAN_BAUD_500K,
/*! 1000 kBit/second */
    CAN_BAUD_1000K,
} E_CANBAUD;

/*! \brief The CAN Bus parameters are used to define the characteristics of the bus and hence its baud rate.

    They are applied to the module's CAN hardware when the BEHAVIOUR_CAN is assigned to a CAN capable resource
    via the CreateResourceBEHAVIOUR_CAN() call. The framework can also use pre-defined values when a specific 
    baud rate is requested. */
typedef struct
{
/*! \brief Prescaler divider factor.

    It determines the ratio between the MPC5xx's IMB clock frequency and the serial clock
    (S-clock). The S-clock is determined as follows SystemFreq / (\c u1PresDiv + 1) */
    uint1 u1PresDiv;
/*! \brief Propergation segment time.

    Valid values are 0...7. Time = (\c u1PropSeg + 1) Time Quanta */
    uint1 u1PropSeg;
/*! \brief Phase buffer segment 1.

    Valid values are 0...7. Time = (\c u1PhaseSeg1 + 1) Time Quanta */
    uint1 u1PhaseSeg1;
/*! \brief Phase buffer segment 1.

    Valid values are 0...7. Time = (\c u1PhaseSeg2 + 1) Time Quanta */
    uint1 u1PhaseSeg2;
/*! \brief Resynchronoization jump width.

    Defines the maximum number of time quanta a bit time may be changed during resynchronization. Valid values
    are 0...3. Jump Width = (\c u1RJW + 1) Time Quanta */
    uint1 u1RJW;
} S_CANBusParams;

/*! \brief Describes possible CAN errors.

    An enumeration has been used to describe the set of errors, but they have values that allow them to
    coexist within a mask. It is possible for more than one of these errors to be detected at any one instant. */
typedef enum
{
/*! Fault confinement passive error */
    CAN_HW_FCS = 0x0010,
/*! The hardware receive error counter has incremented above 96 */
    CAN_HW_RX  = 0x0100,
/*! The hardware transmit error counter has incremented above 96 */
    CAN_HW_TX  = 0x0200,
/*! The bit stuffing in the last transmitted error was correct or not */
    CAN_HW_STUFFERR = 0x0400,
/*! The Message Format of the last transmitted or received message was not correct */
    CAN_HW_FORMERR = 0x0800,
/*! The cyclic redundancy check of the last transmitted or received message was invalid */
    CAN_HW_CRCERR = 0x1000,
/*! TRUE when an acknowledgement has not been correctly received from a transmitted message */
    CAN_HW_ACKERR = 0x2000,
/*! At least one bit sent as dominant was received as recessive */
    CAN_HW_BITERR_DOMINANT = 0x4000,
/*! At least one bit was sent as recessive but received as dominant */
    CAN_HW_BITERR_RECESSIVE = 0x8000,
} E_CANError;

/*! \brief Flags associated with a message and/or a TouCAN message buffer definition

    The flags are logic-ORed into the eFlags members S_CANMessage::eFlags and S_TouCANMessageBufferConfig::eFlags */
typedef enum
{
    CAN_MESSAGE_STANDARD = 0x01,        /*!< Message has a standard (11-bit) identifier. Always applicable */
    CAN_MESSAGE_EXTENDED = 0x02,        /*!< Message has an extended (29-bit) identifier. Always applicable */
    CAN_MESSAGE_TRANSMIT = 0x04,        /*!< Is a Transmission message frame. */
    CAN_MESSAGE_RECEIVE  = 0x08,        /*!< Is a receive message frame. */

/*! Message is to be transmitted in response to a remote frame, but only once. Use TransmitOnCAN() with this
    flag set to schedule a transmission in response to an appropriate remote frame. */
    CAN_MESSAGE_REMOTE_REPONSE_ONCE = 0x10,

/*! Message is to be transmitted in response to a remote frame. Use TransmitOnCAN() with this flag set to
    schedule a transmission in response to an appropriate remote frame. This attribute is like the 
    \ref CAN_MESSAGE_REMOTE_REPONSE_ONCE flag except it allows the response to more than one remote frame */
    CAN_MESSAGE_REMOTE_REPONSE = 0x20,  

/*! Message frame transmission is to be of the remote type. The buffer then sets up to receive. Sets this flag
    when the TouCAN buffer is being defined for receipt via SetResourceAttributesBEHAVIOUR_TOUCAN(),
    SetTouCANMessageBuffer() or SetTouCANMessageBufferWithHandle(). The buffer will issue a remote frame and
    then switch to receive operation using the same Message ID */
    CAN_MESSAGE_REMOTE_SEND = 0x40,

/*! A message frame was missed */
    CAN_MESSAGE_OVERRUN = 0x80,

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

} E_CANMessageFlag;

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

    This function would be supplied by the application and would execute if the framework's CAN hardware
    detected an error. \ref E_CANError describes the error or errors. It should be treated as a mask when
    attempting to detect a particular error. The \p in_uAppSuppliedData parameter is supplied by the
    application when the notification event is defined. The type is sufficiently sized to allow a pointer to
    an object to be stored. Example usage would be to store a pointer to some application object that would
    be of use to the notification function when it executed.
    \code
    void MyCANErrorNotifyFunction(E_CANError in_eCANErrorMask, NativePtrSizedInt_U in_uAppData)
    {
        // Convert the AppData into a pointer [I know I supplied a uint1* when I setup this notification]
        uint1* pu1ErrorCounter = (uint1*)in_uAppData;
                
        // Count an error
        *pu1ErrorCounter++;
        // Use bitwise check rather than equivalence because it is a mask
        if ((in_eCANErrorMask & (CAN_HW_RX | CAN_HW_TX)) != 0)
        {   // Detected some special errors in my app
            *pu1ErrorCounter += 5;
            ...
        }
    }
    \endcode */
typedef void (*CANErrorNotifyFuncPtrType)(E_CANError, NativePtrSizedInt_U in_uAppSuppliedData);

/*! \brief Type describes the CAN error notification information data structure.

    The application can, through a call to the SetResourceAttributesBEHAVIOUR_CAN() function, define how 
    it wishes to be notified should the hardware detect an error. The \p pfCback function will execute,
    supplying the application defined data through the \p uAppDataToSendWithNotify parameter, when an error
    is detected. \p pfCback should be set to \c NULL if the application does not wish to be notified of an
    error. */
typedef struct
{
/*! Pointer to a callback function that the framework will execute if an error is detected. \c NULL disables
    the notification. */
    CANErrorNotifyFuncPtrType pfCback;
/*! This data is supplied as a parameter of the callback function when it executes. The data is sized to
    allow it to hold a pointer type. */
    NativePtrSizedInt_U uAppDataToSendWithNotify;
} S_CANErrorNotifyInfo;

/*! \brief The primary attributes of a CAN message are its payload and its message ID. */
typedef struct
{
/*! This 29bit field captures the CAN Message ID. Use S_CANMessage::eFlags to determine or specify a message
    as being standard (11bit) or extended (29bit). */
    uint4 u4MessageID;
/*! This is the message payload, which can consist of between zero and 8 bytes. Actual length is defined by the
    S_CANMessage::u1Length member. */
    uint1 u1DataArr[8];
/*! This defines the number of payload bytes in this message. Thus it should describes the number of valid bytes
    in the S_CANMessage::u1DataArr member */
    uint1 u1Length;
/*! Flags associated with the message, including whether the it is an extended message or standard message.
    All the possible flags are defined by the \ref E_CANMessageFlag type */
    uint1 eFlags;
} S_CANMessage;

/*! \brief Enumeration describing the possible TouCAN notification events */
typedef enum
{
    CAN_RECEIPT_Q_OVERRUN = 0x01,   /*!< An unread TouCAN message frame has been over-written. Either a
                                         software queue has overrun or the TouCAN message buffer suffered
                                         an overrun condition */
    CAN_RECEIPT = 0x02,             /*!< A TouCAN Message frame has been received */
    CAN_RECEIPT_Q_HALF_FULL = 0x04, /*!< A TouCAN software queue is half full */
    CAN_TRANSMIT_COMPLETE = 0x08,   /*!< Transmission complete event */

/* IF THIS TYPE EXCEEDS 0x80 THEN ALTER THE TYPE OF THE S_TouCANBufferNotify::eEventMaskToNotifyOn MEMBER ACCORDINGLY */

} E_TouCANNotificationEventMask;

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

 This function would be supplied by the application and would execute for enabled notification events. The
 \ref E_TouCANNotificationEventMask describes the event(s) that caused the notification function to execute.
 A handle (\c in_BufferHandle) is supplied as a parameter of the notification function when it executes to
 allow further action to be taken. Thus it would be possible, if the notification was because of the receipt
 of a frame, to then read that frame. The execution would be optimised because of the handle's use.
 
 \p in_uAppSuppliedData is data that was supplied when the notification event was setup. The type is
 sufficiently sized to allow a pointer to an object to be stored. Example usage would be to store a pointer
 to some application object that would be of use to the notification function when it executed.
 \code
 void MyNotifyFunction(E_TouCANNotificationEventMask in_eEventMask, TouCANBufferHandle in_BufferHandle, NativePtrSizedInt_U in_uAppSuppliedData)
 {
     if ((in_eEventMask & CAN_RECEIPT_OVERRUN) != 0)
     {
        ...
     }
     if ((in_eEventMask & CAN_RECEIPT) != 0)
     {
         S_CANMessage MessageBuff;

         SynchReadOnCANWithHandle(in_BufferHandle, &MessageBuff);
         ...
 \endcode */
typedef void (*CANNotifyFuncPtr)(E_TouCANNotificationEventMask, TouCANBufferHandle in_BufferHandle, NativePtrSizedInt_U in_uAppSuppliedData);

/*! \brief Function pointer type that defines the prototype of the CAN receipt snooping notification function

 This function would be supplied by the application and would execute each time the TouCAN device's hardware received
 a CAN Message. The \b TouCANBufferHandle describes the buffer that received the frame. The actual message is described
 by the pointer parmater \b in_pReceivedCANMessage of type \ref S_CANMessage.

 \b in_uAppSuppliedData is data that was supplied when the notification event was setup. The type is
 sufficiently sized to allow a pointer to an object to be stored. Example usage would be to store a pointer
 to some application object that would be of use to the notification function when it executed. */
typedef void (*CANSnooperReceiptNotifyFuncPtr)(TouCANBufferHandle in_BufferHandle, S_CANMessage const* in_pReceivedCANMessage, NativePtrSizedInt_U in_uAppSuppliedData);

/*! \brief Configuration information for the TouCAN Message buffer.

 The S_TouCANMessageBufferConfig::eFlags is used to describe the various attributes of the buffer. While it is an
 enumeration, its members have been organised to allow multiple settings. */
typedef struct
{
/*! Message filter mask to employ with this buffer. Some hardware buffers are forced to share a single message
    mask. An error will result if the definition of this mask does not match an earlier mask definition. */
    uint4 u4MessageIDMask;
/*! Message ID. Only those bits that correspond with 1's in the S_TouCANMessageBufferConfig::u4MessageIDMask are
    checked against the received message frame for a match. */
    uint4 u4MessageID;
/*! The flags of the message ID. The buffer is disabled and its mask freed if neither \ref CAN_MESSAGE_RECEIVE 
    or \ref CAN_MESSAGE_TRANSMIT are set. All possible flags are defined by the \ref E_CANMessageFlag enumeration */
    uint1 eFlags;
} S_TouCANMessageBufferConfig;

/*! \brief A TouCAN Message buffer can have a notification event attached to it. This data structure defines
           this event */
typedef struct
{
/*! \brief Optional notification handler that is to be attached to this TouCAN Message buffer.

    The handler is disabled if this value is set to \c NULL.
    
    Two notification sources are possible when a transmission TouCAN message buffer is established. The
    notification event described here, which would occur upon the successful transmission of each frame (when
    it was enabled) or the frame specific notification that is supplied via the TransmitOnTouCAN() call.
    Only one can be supported. Supplying any form of global notification will result in the frame specific
    notification to be ignored. Do not set \ref USE_CAN_BUFFER_NOTIFY if the frame specific notification
    is required. */
    CANNotifyFuncPtr pfNotify;
/*! Application data that is to be supplied with the notification event when it executes. This data is
    sufficiently sized to allow the storage of a pointer */
    NativePtrSizedInt_U uAppDataToSendOnNotify;
/*! Defines which events require a notification. The events get logic_ORed into the mask. The
    \ref E_TouCANNotificationEventMask enumeration describes the complete list of events */
    uint1 eEventMaskToNotifyOn;
} S_TouCANBufferNotify;

/*! \brief A TouCAN device can have a receipt notification event attached to it. This data structure defines this event.

    This notification can be used to hook into the receipt of any CAN Frame that the TouCAN hardware has been configured
    to receive. This does place additional interrupt burden upon the Framework. Setting the
    S_TouCANReceiptSnooperNotify::pfNotify member to NULL will disable this functionality, which is also
    the default setting. */
typedef struct
{
/*! This is the notification function that is exuected when a CAN Frame is received by the TouCAN hardware.
    Setting this function to NULL will disable this functionality, which is also the default setting. */
    CANSnooperReceiptNotifyFuncPtr pfNotify;
/*! Application data that is to be supplied with the notification event when it executes. This data is
    sufficiently sized to allow the storage of a pointer */
    NativePtrSizedInt_U uAppDataToSendOnNotify;
} S_TouCANReceiptSnooperNotify;
    
/*! \brief Enumeration describes the set of mask definitions that are used to identify the valid CAN attributes
           in the S_CANResourceAttributes, S_TouCANMessageBufferDefn, S_CANCreateResourceAttributes and
           S_CANReadResourceAttributes data structures. */
typedef enum
{
    USE_CAN_ERROR_NOTIFY = 0x0001,      /*!< Selects S_CANResourceAttributes::CANErrorNotifyObj */
    USE_CAN_BUFFER = 0x0002,            /*!< Selects S_CANResourceAttributes::BufferInfoObj */
    USE_CAN_Q_METRICS = 0x0004,         /*!< Selects S_CANReadResourceAttributes::BufferMetricsDefnInfoObj */
    USE_CAN_BUFFER_NOTIFY = 0x0008,     /*!< Selects S_TouCANMessageBufferDefn::NotifyObj */
    USE_CAN_BUFFER_SETTING = 0x0010,    /*!< Selects S_TouCANMessageBufferDefn::ConfigObj */
    USE_CAN_BIT_RATE = 0x0020,          /*!< Selects S_CANReadResourceAttributes::u4BitRate */
    USE_CAN_SW_QUEUES = 0x0040,         /*!< Selects S_CANCreateResourceAttributes::SWQueueObj */
    USE_CAN_BAUD_SETTING = 0x0080,      /*!< Selects S_CANCreateResourceAttributes::eBaud */
    USE_CAN_DYNAMIC_ON_CREATE = 0x0100, /*!< Selects S_CANCreateResourceAttributes::DynamicObj */
    USE_CAN_RECEIPT_SNOOPER = 0x0200,   /*!< Selects S_CANCreateResourceAttributes::SnooperNotifyObj */
    USE_CAN_ERROR_STATUS = 0x0400,      /*!< Selects S_CANReadResourceAttributes::ErrorStatusObj */
/* IF THIS TYPE EXCEEDS 0x8000 THEN ALTER THE TYPE OF THE uValidAttributesMask MEMBER(S) ACCORDINGLY */

} E_CANValidAttributesMask;

/*! Unsigned integer type of sufficient size to hold the attribute masks for a CAN described by \ref E_CANValidAttributesMask */
typedef uint2 CANValidAttributesMask_U;

/*! \brief A TouCAN Message buffer describes a buffer that is used for the reception or transmission of data.

 Use S_TouCANMessageBufferDefn::uValidAttributesMask to define which aspects of the buffer are to be changed. */
typedef struct
{
/*! Describes which attributes [\ref USE_CAN_BUFFER_NOTIFY, \ref USE_CAN_BUFFER_SETTING] in \ref S_TouCANMessageBufferDefn
    are to be applied. All possible attributes are described by the E_CANValidAttributesMask enumeration type. */
    CANValidAttributesMask_U uValidAttributesMask;    

/*! Describes the notification event that is attached to this message buffer. Select with \ref USE_CAN_BUFFER_NOTIFY */
    S_TouCANBufferNotify NotifyObj;
/*! Describes the characteristics of the TouCAN message buffer. Select with \ref USE_CAN_BUFFER_SETTING */
    S_TouCANMessageBufferConfig ConfigObj;
} S_TouCANMessageBufferDefn;

/*! \brief Structure groups a message buffer definition with a buffer identifier */
typedef struct
{
/*! The TouCAN HW buffer that this definition is to apply to */
    E_TouCANBuffer eBufferID;
/*! The TouCAN HW buffer's definition */
    S_TouCANMessageBufferDefn BufferDefnObj;
} S_TouCANMessageBufferInfo;

/*! \brief Structure that describes multiple TouCAN message buffer definitions. */
typedef struct
{
/*! The number of message buffer definitions described by this object. Defines the number of elements in the
    array pointed to by S_TouCANBufferInfo::pTouCANBufferObjArr */
    uint1 u1NumBuffersDefined;
/*! Read only pointer to a buffer of TouCAN message buffer definitions */    
    S_TouCANMessageBufferInfo const* pTouCANBufferObjArr;
} S_TouCANBufferInfo;

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

    The attributes are altered through the use of SetResourceAttributesBEHAVIOUR_TOUCAN(). The data structure
    does not need to be completely filled inorder to be used. The \p 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_CANResourceAttributes CANObj;

    // Going to enable the Error notification object
    CANObj.uValidAttributesMask = USE_CAN_ERROR_NOTIFY;
    // Supply a callback and use uAppDataToSendWithNotify to capture the resource that it's related to 
    CANObj.CANErrorNotifyObj.pfCback = OnCANErrorCback;
    CANObj.CANErrorNotifyObj.uAppDataToSendWithNotify = RES_CAN1;
    \endcode */    
typedef struct
{
/*! Logic-OR the attributes [\ref USE_CAN_ERROR_NOTIFY, \ref USE_CAN_BUFFER]
   that are valid for this instance of the data structure */
    CANValidAttributesMask_U uValidAttributesMask;
/*! CAN error notification definition. Selected with the \ref USE_CAN_ERROR_NOTIFY bit mask */
    S_CANErrorNotifyInfo CANErrorNotifyObj;
/*! TouCAN Message buffer setup. Selected with the \ref USE_CAN_BUFFER bit mask. An array of TouCAN message
    buffers can be supplied with this attribute. */
    S_TouCANBufferInfo BufferInfoObj;
} S_CANResourceAttributes;

/*! Queue metrics data structure. */
typedef struct
{
/*! Fill with the buffer that this metric is to apply to */
    E_TouCANBuffer eBuffer;
/*! The minimum number of free message entries available for use that has been observed in the queue
    since resource creation. */
    uint2 u2MinFreeEntries;
/*! The number of free queue entries available for use. */
    uint2 u2FreeEntries;
/*! The number of CAN frames currently residing in the queue */
    uint2 u2QueueDepth;
} S_QueueMetrics;

/*! Describes a group of TouCAN buffer performance metric data objects */
typedef struct
{
/*! The number of performance metrics defined by this object. Describes the number of elements in the array
    pointer to by S_BufferMetricsInfoObj::pQueueMetricObjArr */
    uint1 u1NumBuffers;
/*! Pointer to an array of TouCAN performance metric objects with S_BufferMetricsInfoObj::u1NumBuffers elements */
    S_QueueMetrics* pQueueMetricObjArr;
} S_BufferMetricsInfoObj;

/*! Describes a group of CANErrorStatus Items, these are obtained when using */
/*  \ref GetResourceAttributesBEHAVIOUR_TOUCAN with \ref USE_CAN_ERROR_STATUS */
typedef struct
{
/*! E_CANError describes the error or errors. It should be treated as a mask when
    attempting to detect a particular error */
    E_CANError eErrorMask;
/*! TouCAN Transmit error counter */
    uint1 u1TXECTR; 
/*! TouCAN Receive error counter */
    uint1 u1RXECTR;
} S_CANErrorStatus;


/*! \brief This data structure describes all of the CAN resource's read attributes.

    The attributes are read through the use of GetResourceAttributesBEHAVIOUR_TOUCAN(). The data structure
    does not need to be completely filled inorder to be used. The \p uValidAttributesMask is a bit field
    member that is used to identify which attributes need to be read. Each attribute is identified with
    a separate bit mask that is logic-ORed into the a mask when an attribute is to be used. */     
typedef struct
{
/*! Logic-OR the attributes [\ref USE_CAN_Q_METRICS, \ref USE_CAN_BIT_RATE, \ref USE_CAN_ERROR_STATUS] that are valid for this instance
    of the data structure */
    CANValidAttributesMask_U uValidAttributesMask;
/*! Selected with \ref USE_CAN_Q_METRICS, this attribute allows the various queue performance metrics to be
    obtained for one or more buffers */
    S_BufferMetricsInfoObj BufferMetricsDefnInfoObj;
/*! Selected with \ref USE_CAN_BIT_RATE, this attribute returns the CAN bus bit rate that was defined when
    the behaviour was assigned to the resource */
    uint4 u4BitRate;
/*! Selected with \ref USE_CAN_ERROR_STATUS, this attribute returns a structure containing the current
    error status of the channel */
    S_CANErrorStatus ErrorStatusObj;

} S_CANReadResourceAttributes;

/*! Queue attributes */
typedef struct
{
/*! Identifies the buffer that this queue is to be applied to */
    E_TouCANBuffer eBufferId;
/*! It is possible for a queue to be used for either transmission or reception, but their RAM usage is
    different. This attribute allows the appropriate queue to be specified. Set to TRUE for a transmission
    queue and FALSE for a reception queue. The queue will not be used if its type does not match the current
    configuration of the hardware buffer. That is, if a reception queue was specified, then it would not be
    available for use if the buffer was currently being used for transmission. */
    bool1 b1IsForTransmission;
/*! This attribute provides the framework with an estimate on the expected number of TouCAN message frames
    that will need to be buffered. */
    uint2 u2MinQueueDepth;
} S_CANQueueDefn;

/*! Data structure groups software queue definitions */
typedef struct
{
/*! The number of TouCAN message buffer queue definitions described by this object. Defines the number of
    elements in the array pointed to by S_CANSoftwareQueues::pQueueDefnObjArr. Setting to zero will indicate
    that there are no software queue definitions */
    NativeVar_U uNumQueueDefns;
/*! Pointer to an array of software queue definition objects. The number of elements in the array is described
    by the S_CANSoftwareQueues::uNumQueueDefns attribute. Setting to NULL indicates that there are no
    software queue definitions defined. */
    S_CANQueueDefn* pQueueDefnObjArr;
} S_CANSoftwareQueues;

/*! \brief This data structure describes the creation attributes for a CAN 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_TOUCAN() function.
    
    The \c uValidAttributesMask is used to select those attributes that have been defined and those attributes
    which are to accept default values. */
typedef struct
{
/*! Logic-OR the attributes [\ref USE_CAN_BAUD_SETTING, \ref USE_CAN_SW_QUEUES, \ref USE_CAN_DYNAMIC_ON_CREATE,
    \ref USE_CAN_RECEIPT_SNOOPER] that are valid for this instance of the data structure. The framework will
    employ the creation defaults for those attributes that are left undefined. */
    CANValidAttributesMask_U uValidAttributesMask;

/*! \brief The baud rate that the bus should operate at. Default is \ref CAN_BAUD_250K. 

    This is the simplified method of setting the baud rate. When employed the \ref S_CANBusParams settings
    take on Framework recommended values. Supply a value of \ref CAN_BAUD_CUSTOM if the application wants the
    bus to take on the values defined by \ref S_CANBusParams. Select this attribute with \ref USE_CAN_BAUD_SETTING  */
    E_CANBAUD eBaud;

/*! \brief The bus parameters to be applied to the CAN bus.

    These values are only applied if the S_CANCreateResourceAttributes::eBaud is illegal or contains a
    value of \ref CAN_BAUD_CUSTOM. */
    S_CANBusParams BusParamsObj;

/*! \brief Software queues can be optionally associated with each of the buffers. This data structure allows
    these options to be specified. Include the \ref USE_CAN_SW_QUEUES if software queues are required.
    
    Software queues can only be asscoiated with a resource when it is created. There are some key reasons for
    this.
    - It minimise free store memory fragmentation, which can result if the free store memory is being consumed
    and released frequently.
    - Resource creation typically occurs during application initialisation and so it will be reasonable to assume
    that if the memory is available during application testing, then it will always be this way. It is possible,
    for an application to fail intermittently with ERROR_OUT_OF_MEMORY because of race conditions with other
    processes that also use free store memory if creation is allowed during normal runtime.
    - Some race conditions do not need to be handled, which simplifies the device driver and consequently
    minimises the footprint of the framework. */
    S_CANSoftwareQueues SWQueueObj;
/*! Initial values of the runtime attributes, which can be later altered through with SetResourceAttributesBEHAVIOUR_CAN().
    Select this attribute with the \ref USE_CAN_DYNAMIC_ON_CREATE bit mask */
    S_CANResourceAttributes DynamicObj;

/*! \brief Snooping CAN frame receipt notification

    A notification can be used to hook into the receipt of any CAN Frame that the TouCAN hardware has been configured
    to receive. This does place additional interrupt burden upon the Framework. The default setting is to disable this
    notification. Select this attribute with the \ref USE_CAN_RECEIPT_SNOOPER bit mask. */
    S_TouCANReceiptSnooperNotify SnooperNotifyObj;
} S_CANCreateResourceAttributes;

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

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

NativeError_S GetTouCANHandle(E_ModuleResource, E_TouCANBuffer, TouCANBufferHandle* out_pHandle);
NativeError_S GetTouCANLastLegalBufferId(E_ModuleResource in_eResource, E_TouCANBuffer* out_pBufferId);

NativeError_S SetTouCANMessageBuffer(E_ModuleResource, E_TouCANBuffer, S_TouCANMessageBufferDefn const* in_pBufferDefnObj);
NativeError_S SetTouCANMessageBufferWithHandle(TouCANBufferHandle, S_TouCANMessageBufferDefn const* in_pBufferDefnObj);

NativeError_S FreeTouCANMessageBuffer(E_ModuleResource, E_TouCANBuffer);
NativeError_S FreeTouCANMessageBufferWithHandle(TouCANBufferHandle);

NativeError_S GetTouCANMessageBufferFlags(E_ModuleResource, E_TouCANBuffer, E_CANMessageFlag* out_peFlag);
NativeError_S GetTouCANMessageBufferFlagsWithHandle(TouCANBufferHandle, E_CANMessageFlag* out_peFlag);

NativeError_S TransmitOnTouCAN(E_ModuleResource, E_TouCANBuffer, S_CANMessage const* in_pMessageToSendObj, CANNotifyFuncPtr, NativePtrSizedInt_U in_AppDataToSendWithNotify);
NativeError_S TransmitOnTouCANWithHandle(TouCANBufferHandle, S_CANMessage const* in_pMessageToSendObj, CANNotifyFuncPtr, NativePtrSizedInt_U in_AppDataToSendWithNotify);

NativeError_S SynchReadFromTouCAN(E_ModuleResource, E_TouCANBuffer, S_CANMessage* out_pMessage, uint2 in_u2TimeOutInMilliSecs);
NativeError_S SynchReadFromTouCANWithHandle(TouCANBufferHandle in_Handle, S_CANMessage* out_pMessageObj, uint2 in_u2TimeOutInMilliSecs);

/* DO NOT use these functions directly. They are implicitly called through the use of the CreateResource() */
/*   and SetResourceAttributes() macro functions                                                           */
NativeError_S CreateResourceBEHAVIOUR_TOUCAN(E_ModuleResource, S_CANCreateResourceAttributes const*);
NativeError_S SetResourceAttributesBEHAVIOUR_TOUCAN(E_ModuleResource, S_CANResourceAttributes const*);
NativeError_S GetResourceAttributesBEHAVIOUR_TOUCAN(E_ModuleResource, S_CANReadResourceAttributes*);

#endif /* __RESOURCE_CAN_H */

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