/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   Serial Communications Resource Framework API Header File
::   Copyright   :   (C)2002-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file  Resource_Comm.h
 \brief The BEHAVIOUR_COMM behaviour exposes the framework's communication interface behaviour.
 
 The interface is modelled on a universal asynchronous receiver transmitter (UART) type serial communications
 interface resource. An application can, through this behaviour, reserve a serial communications resource and
 then use it to send and receive data over the communications link.

 This behaviour can be used to employ a module's serial communications interface (SCI) hardware. It can also
 be used to tunnel communications typical of an SCI link through the modules CAN hardware. Use of this behaviour
 on CAN hardware is limited to point-to-point communications. The BEHAVIOUR_CAN can be used if such operation
 is too limiting.

 See \ref commoverview, \ref commusage
*/

#ifndef __RESOURCE_COMM_H
#define __RESOURCE_COMM_H

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

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

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

/*! Describes possible communications errors. An enumeration has been used to describe the set of
    communications 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
{
    COMM_NO_ERROR        = 0x00,
    COMM_HW_FRAMING      = 0x01, /*!< Framing error detected by the communication hardware. Received data was
                                      ignored. */
    COMM_HW_NOISE        = 0x02, /*!< Noise error detected by the communication hardware. Received data was
                                      ignored. */
    COMM_HW_OVERRUN      = 0x04, /*!< Further data was received from the link before the framework had time
                                      to process previously received data. The baud rate is potentially too
                                      high. Received data was ignored. */
    COMM_HW_OVERRUN_FRAME= 0x05, /*!< Combines the COMM_HW_OVERRUN and COMM_HW_FRAMING errors. Often they occur
                                      together */ 
    COMM_SW_BUFF_OVERRUN = 0x08, /*!< The software receive queue has overrun because it has not been read from
                                      the queue by the application or purged. Received data was ignored. */
    COMM_INTERNAL        = 0x10, /*!< Unexpected internal problem */
} E_CommsError;

/*! Function pointer type that defines the prototype of the communications error notification function.

    This function would be supplied by the application and would execute if the framework's communications
    hardware detected an error. Communications errors account for problems like buffer overrun and
    communications framing errors. The \b 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. For example, the object may be a pointer to
    a variable that counts the number of communications errors detected by this resource.
*/
typedef void (*CommErrorNotifyFuncPtrType)(E_CommsError, NativePtrSizedInt_U in_uAppSuppliedData);

/*! Supported wake notification events. */
typedef enum
{
/*! Idle communications wake event.
   
    Idle is detected when the receieve buffer becomes idle again after the receipt of some data that has not
    already been associated with a scheduled data read. The intent of this event is to allow the application
    to be notified when a new data packet has been received.
    
    <IMG src="WakeNotifyFig.wmf" alt="Wake Notify Example Figure" align="middle" border=0> */
    COMM_IDLE = 0x01
} E_CommWakeEvent;

/*! Type describes the communications error notification information data structure. The application can,
    through a call to the SetResourceAttributesBEHAVIOUR_COMM() function, define how it wishes to be notified
    should the hardware detect a communications error. The \p pfCback function will execute, supplying the
    application defined data through the \p uAppData parameter, when a hardware error is detected. \p pfCback
    should be set to \c NULL if the application does not wish to be notified of a communications error. */
typedef struct
{
    CommErrorNotifyFuncPtrType pfCback; /*!< Pointer to a callback function that the framework will execute if
                                             a communications error is detected. \c NULL disables the notification. */
    NativePtrSizedInt_U uAppData;       /*!< 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 */
} S_CommsErrorNotifyInfo;

/*! Function pointer type that defines the prototype of the wake notification callback function.

    The particular wake event is identified by the \ref E_CommWakeEvent parameter. The most common use of the
    wake event is to detect idle. See \ref E_CommWakeEvent::COMM_IDLE. The intent of this event would be to
    allow the defined function to execute, allowing the application to be notified when a new data packet had
    been received.
*/
typedef void (*CommWakeNotifyFuncPtrType)(E_CommWakeEvent, NativePtrSizedInt_U in_uAppSuppliedData);

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

    The application can, through a call to the SetResourceAttributesBEHAVIOUR_COMM() function, define whether
    it wishes to be notified if the framework detects a wake event. See \ref CommWakeNotifyFuncPtrType and
    \ref E_CommWakeEvent. */
typedef struct
{
    CommWakeNotifyFuncPtrType pfCback;  /*!< Pointer to a callback function that the framework will execute upon
                                             detecting the wake event. */
    NativePtrSizedInt_U uAppData;       /*!< 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 */
    E_CommWakeEvent eWakeEventMask;     /*!< Defines which wake events the application wants to be notified of.
                                             The enumeration describes a bit mask where each event to be
                                             enabled is logically-ORed into the member */
} S_CommWakeNotifyInfo;

/*! \brief Read data notification function pointer type.

    This function executes when all the bytes requested by an application read have been receieved or the
    requested read times out. \p in_pu1RXBuff points to a buffer that contains the recieved data when the
    the read was successful. This parameter will be \c NULL if the notification function executes
    because the request timed out. \p in_u2NumBytesInBuffer will also be zero when a read request times out.

    \p in_uAppSuppliedData is application data that was supplied by the application when the callback was
    defined.    
*/
typedef void (*CommReadNotifyFuncPtrType)(uint1* in_pu1RXBuff, uint2 in_u2NumBytesInBuffer, NativePtrSizedInt_U in_uAppSuppliedData);

/*! \brief Transmit complete function pointer type.

    This function executes when a requested serial stream of data has been transmitted onto the wire. The
    function supplies the application data as a parameter. The application data is defined when the callback
    was supplied to the communication resource. */
typedef void (*CommTxCompleteNotifyFuncPtrType)(NativePtrSizedInt_U in_uAppData);

#define COMM_TX_QUEUE            ((NativeVar_U)(0x01))
#define COMM_RX_QUEUE            ((NativeVar_U)(0x02))

typedef enum
{
    USE_COMM_ERROR_NOTIFY = 0x0001,     /*!< Selects S_CommResourceAttributes::CommsErrorNotifyObj */
    USE_COMM_BAUD = 0x0002,             /*!< Selects S_CommReadResourceAttributes::u4RequestedBaudRate and
                                             S_CommResourceAttributes::u4Baud */
    USE_COMM_WAKE_NOTIFY = 0x0004,      /*!< Selects S_CommResourceAttributes::WakeNotifyObj */
    USE_COMM_MIN_TX_Q_FREE =0x0008,     /*!< Selects S_CommReadResourceAttributes::u2MinTXQueueBytesFree */
    USE_COMM_TX_Q_FREE = 0x0010,        /*!< Selects S_CommReadResourceAttributes::u2TXQueueBytesFree */
    USE_COMM_MIN_RX_Q_FREE = 0x0020,    /*!< Selects S_CommReadResourceAttributes::u2MinRXQueueBytesFree */
    USE_COMM_RX_BYTES_UNREAD = 0x0040,  /*!< Selects S_CommReadResourceAttributes::u2RXQueueDepth */
    USE_COMM_MAX_BAUD_RATE = 0x0080,    /*!< Selects S_CommReadResourceAttributes::u4RecommendedMaxBaudRate */
    USE_COMM_ACTUAL_BAUD = 0x0100,      /*!< Selects S_CommReadResourceAttributes::u4ActualBaudRate */
    USE_COMM_DYNAMIC_ON_CREATE = 0x0200, /*!< Selects S_CommCreateResourceAttributes::DynamicObj */

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

} E_CommValidAttributesMask;

/*! This data structure describes attributes that can be read from a communications resource */
typedef struct
{
/*! Logic-OR the attributes in the data structure that will be valid. Valid attributes include:
    \ref USE_COMM_MIN_TX_Q_FREE, \ref USE_COMM_TX_Q_FREE, \ref USE_COMM_MIN_RX_Q_FREE, \ref USE_COMM_BAUD,
    \ref USE_COMM_ACTUAL_BAUD, \ref USE_COMM_MAX_BAUD_RATE and \ref USE_COMM_RX_BYTES_UNREAD */
    uint2 uValidAttributesMask;

/*! The minimum number of free bytes available for use in transmission that has been observed in the TX queue
    since resource creation. \ref USE_COMM_MIN_TX_Q_FREE enables this attribute. */
    uint2 u2MinTXQueueBytesFree;

/*! The number of bytes currently free in the TX queue for use in transmission. \ref USE_COMM_TX_Q_FREE enables
    the attribute. */
    uint2 u2TXQueueBytesFree;

/*! The minimum number of free bytes that has been observed as available for the receipt of data, observed
    since resource creation. \ref USE_COMM_MIN_RX_Q_FREE enables the attribute. */
    uint2 u2MinRXQueueBytesFree;

/*! The number of unread bytes that currently exists in the RX queue. \ref USE_COMM_RX_BYTES_UNREAD selects the
    attribute. */
    uint2 u2RXQueueDepth;

/*! The last baud rate requested for the link. \ref USE_COMM_BAUD selects the attribute. */
    uint4 u4RequestedBaudRate;
/*! The actual baud rate in use by the link. Is the actual baud rate and so can be used to determine
    rounding effects because of internal frequencies etc. \ref USE_COMM_ACTUAL_BAUD selects the attribute */
    uint4 u4ActualBaudRate;
/*! Describes the recommended maximum allowed baud rate for the resource. This value is selected based upon
    the transmission and receive capabilities of the physical layer and the load placed on the framework to
    service the resource reliably without degrading the performance of other systems. Select this attribute
    with \ref USE_COMM_MAX_BAUD_RATE. */
    uint4 u4RecommendedMaxBaudRate;
} S_CommReadResourceAttributes;

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

    The attributes are altered through the use of SetResourceAttributesBEHAVIOUR_COMM(). 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_CommResourceAttributes CommObj;

    // Going to change the Comm baud and the wake notification event
    CommObj.uValidAttributesMask = USE_COMM_BAUD | USE_COMM_WAKE_NOTIFY;
    \endcode
*/    
typedef struct
{
/*! Logic-OR the attributes [\ref USE_COMM_ERROR_NOTIFY, \ref USE_COMM_BAUD, \ref USE_COMM_WAKE_NOTIFY ] that are
    valid for this instance of the data structure */
    uint2 uValidAttributesMask;
/*! Communications error notification definition. Selected with the \ref USE_COMM_ERROR_NOTIFY bit mask */
    S_CommsErrorNotifyInfo CommsErrorNotifyObj;
/*! Wake notification definition. Selected with \ref USE_COMM_WAKE_NOTIFY */
    S_CommWakeNotifyInfo WakeNotifyObj;
/*! The baud rate that the link is to operate at. A call to alter the link's baud rate will block until the
    current byte (if any) has been transmitted. Selected with \ref USE_COMM_BAUD */
    uint4 u4Baud;
} S_CommResourceAttributes;

/*! Type describing a read only pointer to a communication resource's dynamic attribute structure
    \ref S_CommResourceAttributes */
typedef S_CommResourceAttributes const* S_CommResourceAttributesPtr;

/*! \brief This data structure describes the creation attributes for a communications 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_COMM() function. */
typedef struct
{
/*! Logic-OR the attributes [\ref USE_COMM_DYNAMIC_ON_CREATE ] that are valid for this instance of the data
    structure */
    uint2 uValidAttributesMask;
    
/*! \brief The minimum size that the framework should reserve for the transmit buffer in bytes. The framework
    will use this value as a guide when it declares the buffer.

    This value should be sized based upon the maximum size of a valid transmission packet for the protocol(s)
    that will be using the communications resource. GetResourceAttributesBEHAVIOUR_COMM() can be used to learn
    of overall queue performance while running via the S_CommReadResourceAttributes::u2MinTXQueueBytesFree
    attribute. This can be used to better select the required size of the transmit buffer. */
    uint2 u2MinSizeOfTXBuffer;          
                                             
/*! \brief The minimum size that the framework should reserve for the receive buffer in bytes. The framework
    will use this value as a guide when it declares the buffer.
        
    This value should be sized based upon the maximum size of a valid receive packet for the protocol(s)
    that will be using the communications resource. GetResourceAttributesBEHAVIOUR_COMM() can be used to learn
    of overall queue performance while running via the S_CommReadResourceAttributes::u2MinRXQueueBytesFree
    attribute. This can be used to better select the required size of the receive buffer. */
    uint2 u2MinSizeOfRXBuffer;

/*! Used as the source CityID that will be used with CAN tunnelling transmission scheme. Tunnelling allows
    a point-to-point, master/slave communications link to be established over CAN. The module is always
    the slave device when a link of this type is established. Use BEHAVIOUR_CAN if precise control over
    the CAN hardware is required. Also see \ref canhwsummary

    This value will be placed in ID[15..8] of the CAN Message ID receive queue. ID[7..0] and ID[23..16]
    will be masked. Thus any extended message ID logic-ANDed with 0x0000XX00 that equates to \p u1MyCANCityID
    will be received and its payload placed into the receive queue.
    
    It will also be placed into ID[7..0] of any transmitted CAN message. The ID[15..8] will be filled with the
    contents of ID[7..0] of MessageID of the last received CAN message and is why CAN tunnelling can only be
    used for master/slave point-to-point communication. */
    uint1 u1MyCANCityID;

/*! Initial values of the runtime attributes, which can be later altered through a call to SetResourceAttributesBEHAVIOUR_COMM().
    Select this attribute with the \ref USE_COMM_DYNAMIC_ON_CREATE bit mask. */
    S_CommResourceAttributes DynamicObj;
} S_CommCreateResourceAttributes;

/*! Type describing a read only pointer to a communication resource's creation attribute data structure
    \ref S_CommCreateResourceAttributes */
typedef S_CommCreateResourceAttributes const* S_CommCreateResourceAttributesPtr;

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

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

/* DO NOT use these functions directly. They are implicitly called through the use of the CreateResource() */
/*   and SetResourceAttributes() macro functions                                                           */
NativeError_S CreateResourceBEHAVIOUR_COMM(E_ModuleResource, S_CommCreateResourceAttributes const*);
NativeError_S SetResourceAttributesBEHAVIOUR_COMM(E_ModuleResource, S_CommResourceAttributes const*);
NativeError_S GetResourceAttributesBEHAVIOUR_COMM(E_ModuleResource, S_CommReadResourceAttributes*);

NativeError_S TransmitOnComm(E_ModuleResource, uint2 in_u2NumBytesToSend, void const* in_pData, CommTxCompleteNotifyFuncPtrType, NativePtrSizedInt_U in_uAppData);
NativeError_S AsynchReadFromComm(E_ModuleResource, uint2 in_u2NumBytesToRead, CommReadNotifyFuncPtrType, NativePtrSizedInt_U in_uAppData, uint2 in_u2ReadTimeOutInMillisecs);
NativeError_S SynchReadFromComm(E_ModuleResource, uint2 in_u2NumBytesToRead, void* out_pBuffer, uint2 in_u2TimeoutInMilliSecs);
NativeError_S SynchScanFromComm(E_ModuleResource, uint2 in_u2NumBytesToRead, void* out_pBuffer);
NativeError_S PurgeCommQueue(E_ModuleResource in_eResource, NativeVar_U in_uQueueBitMask);

#endif /* __RESOURCE_COMM_H */

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