// Hwi : Hardware interface
#ifndef HwiEUART_H
#define HwiEUART_H


//-----
// define Data Field Access
//

// Data can be 8bit 16bit, 32bit
// FieldDefine is bit field mask, Value Range and location.
// FieldDefine_Range is value range.
// FieldDefine_Shift is bit location.

#define _SetDataField(Data, FieldDefine, Value) \
    Data = (Data & ~ FieldDefine ) | ((Value & FieldDefine##_Range) << FieldDefine##_Shift);
    
    // if Data is register. the following code have some bug.
    // because register value should alter one time, not two assign.
    //Data &= ~##FieldDefine##;
    //Data |= ((Value) & ##FieldDefine##_Range) << ##FieldDefine##_Shift;
    
#define _GetDataField(Data, FieldDefine, Variable) \
    Variable = ((Data) & FieldDefine) >> FieldDefine##_Shift;
    
#define _OrDataField(Data, FieldDefine, Value) \
    Data |= ((Value) & FieldDefine##_Range) << FieldDefine##_Shift;

#define _SetPointerField(Data, FieldDefine, Pointer) \
    Data = (Data & ~ FieldDefine) | (((Pointer >> FieldDefine##_Shift) & FieldDefine##_Range) << FieldDefine##_Shift);
    //Data &= ~##FieldDefine##;
    //Data |= ((Pointer>>##FieldDefine##_Shift) & ##FieldDefine##_Range) << ##FieldDefine##_Shift;
    
#define _GetPointerField(Data, FieldDefine, Variable) \
    Variable = ((Data) & FieldDefine );

//-----
//  Register Interface
//

#define EUARTRegisters_Length                               0x08

#define EUARTRegOffset_Size                                 1

#define EUARTRegOffset_HwiDivisorLatchLowReg                0x00
#define EUARTRegOffset_HwiDivisorLatchHighReg               0x01

#define EUARTRegOffset_HwiReceiverBufferReg                 0x00
#define EUARTRegOffset_HwiTransmitterHoldingReg             0x00
#define EUARTRegOffset_HwiInterruptEnableReg                0x01
#define EUARTRegOffset_HwiInterruptIdentificationReg        0x02
#define EUARTRegOffset_HwiFIFOControlReg                    0x02
#define EUARTRegOffset_HwiLineControlReg                    0x03
#define EUARTRegOffset_HwiModemControlReg                   0x04
#define EUARTRegOffset_HwiLineStatusReg                     0x05
#define EUARTRegOffset_HwiModemStatusReg                    0x06
#define EUARTRegOffset_HwiScratchpadReg                     0x07

#define EUARTDMARegisters_Length                            0x1C

//DMA Control & Status Register 
#define EUARTRegOffset_HwiDMAControl0Reg                    0x00
#define EUARTRegOffset_HwiDMAControl1Reg                    0x01
#define EUARTRegOffset_HwiDMAStatusReg                      0x02
//#define EUARTRegOffset_HwiDMAStatsReg                       0x03

//DMA Tx Buffer Address Register
#define EUARTRegOffset_HwiDMATxBufferAddressReg             0x04

//DMA Rx Buffer Address Register
#define EUARTRegOffset_HwiDMARxBufferAddressReg             0x08

//DMA Interrupt Enable Register
#define EUARTRegOffset_HwiDMAInterruptEnableReg             0x0C

//DMA Interrupt Status Register
#define EUARTRegOffset_HwiDMAInterruptStatusReg             0x10

//Tx Segment Data Length Register
#define EUARTRegOffset_HwiDMATx0DataLengthReg               0x14
#define EUARTRegOffset_HwiDMATx1DataLengthReg               0x15

//Rx Segment Data Length Register
#define EUARTRegOffset_HwiDMARx0DataCountReg                0x18
#define EUARTRegOffset_HwiDMARx1DataCountReg                0x19


#define EUARTRegID_HwiDivisorLatchLowReg                    0
#define EUARTRegID_HwiDivisorLatchHighReg                   1
#define EUARTRegID_HwiReceiverBufferReg                     2
#define EUARTRegID_HwiTransmitterHoldingReg                 3
#define EUARTRegID_HwiInterruptEnableReg                    4
#define EUARTRegID_HwiInterruptIdentificationReg            5
#define EUARTRegID_HwiFIFOControlReg                        6
#define EUARTRegID_HwiLineControlReg                        7
#define EUARTRegID_HwiModemControlReg                       8
#define EUARTRegID_HwiLineStatusReg                         9
#define EUARTRegID_HwiModemStatusReg                        10
#define EUARTRegID_HwiScratchpadReg                         11

#define HwiInterruptEnableReg_ReceivedDataAvailable         0x00000001
#define HwiInterruptEnableReg_TransmitterHoldingEmpty       0x00000002
#define HwiInterruptEnableReg_LineStatus                    0x00000004
#define HwiInterruptEnableReg_ModemStatus                   0x00000008

#define HwiInterruptEnableReg_ReceivedDataAvailable_Shift   (0)
#define HwiInterruptEnableReg_TransmitterHoldingEmpty_Shift (1)
#define HwiInterruptEnableReg_LineStatus_Shift              (2)
#define HwiInterruptEnableReg_ModemStatus_Shift             (3)

#define HwiInterruptEnableReg_ReceivedDataAvailable_Range   0x00000001
#define HwiInterruptEnableReg_TransmitterHoldingEmpty_Range 0x00000001
#define HwiInterruptEnableReg_LineStatus_Range              0x00000001
#define HwiInterruptEnableReg_ModemStatus_Range             0x00000001


#define HwiInterruptIdentificationReg_NoPending             0x00000001
#define HwiInterruptIdentificationReg_ID                    0x0000000E

#define HwiInterruptIdentificationReg_NoPending_Shift       (0)
#define HwiInterruptIdentificationReg_ID_Shift              (1)

#define HwiInterruptIdentificationReg_NoPending_Range       0x00000001
#define HwiInterruptIdentificationReg_ID_Range              0x00000007


#define HwiFIFOControlReg_FIFOEnable                        0x00000001
#define HwiFIFOControlReg_RxFIFOReset                       0x00000002
#define HwiFIFOControlReg_TxFIFOReset                       0x00000004
#define HwiFIFOControlReg_RxFIFOTriggerLevel                0x000000C0
//#define HwiFIFOControlReg_DMA for legacy software

#define HwiFIFOControlReg_FIFOEnable_Shift                  (0)
#define HwiFIFOControlReg_RxFIFOReset_Shift                 (1)
#define HwiFIFOControlReg_TxFIFOReset_Shift                 (2)
#define HwiFIFOControlReg_RxFIFOTriggerLevel_Shift          (6)

#define HwiFIFOControlReg_FIFOEnable_Range                  0x00000001
#define HwiFIFOControlReg_RxFIFOReset_Range                 0x00000001
#define HwiFIFOControlReg_TxFIFOReset_Range                 0x00000001
#define HwiFIFOControlReg_RxFIFOTriggerLevel_Range          0x00000003


#define HwiLineControlReg_WordLengthSelect                  0x00000003
#define HwiLineControlReg_StopBitsSelect                    0x00000004
#define HwiLineControlReg_ParityEnable                      0x00000008
#define HwiLineControlReg_ParitySelect                      0x00000030
#define HwiLineControlReg_TransmitBreak                     0x00000040
#define HwiLineControlReg_DivisorLatchAccess                0x00000080

#define HwiLineControlReg_WordLengthSelect_Shift            (0)
#define HwiLineControlReg_StopBitsSelect_Shift              (2)
#define HwiLineControlReg_ParityEnable_Shift                (3)
#define HwiLineControlReg_ParitySelect_Shift                (4)
#define HwiLineControlReg_TransmitBreak_Shift               (6)
#define HwiLineControlReg_DivisorLatchAccess_Shift          (7)

#define HwiLineControlReg_WordLengthSelect_Range            0x00000003
#define HwiLineControlReg_StopBitsSelect_Range              0x00000001
#define HwiLineControlReg_ParityEnable_Range                0x00000001
#define HwiLineControlReg_ParitySelect_Range                0x00000003
#define HwiLineControlReg_TransmitBreak_Range               0x00000001
#define HwiLineControlReg_DivisorLatchAccess_Range          0x00000001


#define HwiModemControlReg_DTRPin                           0x00000001
#define HwiModemControlReg_RTSPin                           0x00000002
#define HwiModemControlReg_Out1Pin                          0x00000004
#define HwiModemControlReg_Out2Pin                          0x00000008
#define HwiModemControlReg_LoopbackEnable                   0x00000010

#define HwiModemControlReg_DTRPin_Shift                     (0)
#define HwiModemControlReg_RTSPin_Shift                     (1)
#define HwiModemControlReg_Out1Pin_Shift                    (2)
#define HwiModemControlReg_Out2Pin_Shift                    (3)
#define HwiModemControlReg_LoopbackEnable_Shift             (4)

#define HwiModemControlReg_DTRPin_Range                     0x00000001
#define HwiModemControlReg_RTSPin_Range                     0x00000001
#define HwiModemControlReg_Out1Pin_Range                    0x00000001
#define HwiModemControlReg_Out2Pin_Range                    0x00000001
#define HwiModemControlReg_LoopbackEnable_Range             0x00000001


#define HwiLineStatusReg_DataReady                          0x00000001
#define HwiLineStatusReg_OverrunError                       0x00000002
#define HwiLineStatusReg_ParityError                        0x00000004
#define HwiLineStatusReg_FamingError                        0x00000008
#define HwiLineStatusReg_BreakSignal                        0x00000010
#define HwiLineStatusReg_TransmitterHodingEmpty             0x00000020
#define HwiLineStatusReg_TransmitterEmpty                   0x00000040
#define HwiLineStatusReg_ErrorInRxFIFO                      0x00000080

#define HwiLineStatusReg_DataReady_Shift                    (0)
#define HwiLineStatusReg_OverrunError_Shift                 (1)
#define HwiLineStatusReg_ParityError_Shift                  (2)
#define HwiLineStatusReg_FamingError_Shift                  (3)
#define HwiLineStatusReg_BreakSignal_Shift                  (4)
#define HwiLineStatusReg_TransmitterHodingEmpty_Shift       (5)
#define HwiLineStatusReg_TransmitterEmpty_Shift             (6)
#define HwiLineStatusReg_ErrorInRxFIFO_Shift                (7)

#define HwiLineStatusReg_DataReady_Range                     0x00000001
#define HwiLineStatusReg_OverrunError_Range                  0x00000001
#define HwiLineStatusReg_ParityError_Range                   0x00000001
#define HwiLineStatusReg_FamingError_Range                   0x00000001
#define HwiLineStatusReg_BreakSignal_Range                   0x00000001
#define HwiLineStatusReg_TransmitterHodingEmpty_Range        0x00000001
#define HwiLineStatusReg_TransmitterEmpty_Range              0x00000001
#define HwiLineStatusReg_ErrorInRxFIFO_Range                 0x00000001


#define HwiModemStatusReg_CTSChange                         0x00000001
#define HwiModemStatusReg_DSRChange                         0x00000002
#define HwiModemStatusReg_RIChange                          0x00000004
#define HwiModemStatusReg_DCDChange                         0x00000008
#define HwiModemStatusReg_CTS                               0x00000010
#define HwiModemStatusReg_DSR                               0x00000020
#define HwiModemStatusReg_RI                                0x00000040
#define HwiModemStatusReg_DCD                               0x00000080

#define HwiModemStatusReg_CTSChange_Shift                   (0)
#define HwiModemStatusReg_DSRChange_Shift                   (1)
#define HwiModemStatusReg_RIChange_Shift                    (2)
#define HwiModemStatusReg_DCDChange_Shift                   (3)
#define HwiModemStatusReg_CTS_Shift                         (4)
#define HwiModemStatusReg_DSR_Shift                         (5)
#define HwiModemStatusReg_RI_Shift                          (6)
#define HwiModemStatusReg_DCD_Shift                         (7)

#define HwiModemStatusReg_CTSChange_Range                   0x00000001
#define HwiModemStatusReg_DSRChange_Range                   0x00000001
#define HwiModemStatusReg_RIChange_Range                    0x00000001
#define HwiModemStatusReg_DCDChange_Range                   0x00000001
#define HwiModemStatusReg_CTS_Range                         0x00000001
#define HwiModemStatusReg_DSR_Range                         0x00000001
#define HwiModemStatusReg_RI_Range                          0x00000001
#define HwiModemStatusReg_DCD_Range                         0x00000001


#define HwiDMAControl0Reg_DMAEnable                         0x00000001
#define HwiDMAControl0Reg_HardReset                         0x00000002
#define HwiDMAControl0Reg_RxSegmentTriggerLevel             0x0000001C
#define HwiDMAControl0Reg_DebugBit                          0x00000080

#define HwiDMAControl0Reg_DMAEnable_Shift                   (0)
#define HwiDMAControl0Reg_HardReset_Shift                   (1)
#define HwiDMAControl0Reg_RxSegmentTriggerLevel_Shift       (2)
#define HwiDMAControl0Reg_DebugBit_Shift                    (7)

#define HwiDMAControl0Reg_DMAEnable_Range                   0x00000001
#define HwiDMAControl0Reg_HardReset_Range                   0x00000001
#define HwiDMAControl0Reg_RxSegmentTriggerLevel_Range       0x00000007
#define HwiDMAControl0Reg_DebugBit_Range                    0x00000001

#define HwiDMAControl1Reg_TxSegment0Ready                   0x00000001
#define HwiDMAControl1Reg_TxSegment1Ready                   0x00000002
#define HwiDMAControl1Reg_RxSegment0Ready                   0x00000004
#define HwiDMAControl1Reg_RxSegment1Ready                   0x00000008

#define HwiDMAControl1Reg_TxSegment0Ready_Shift             (0)
#define HwiDMAControl1Reg_TxSegment1Ready_Shift             (1)
#define HwiDMAControl1Reg_RxSegment0Ready_Shift             (2)
#define HwiDMAControl1Reg_RxSegment1Ready_Shift             (3)

#define HwiDMAControl1Reg_TxSegment0Ready_Range             0x00000001
#define HwiDMAControl1Reg_TxSegment1Ready_Range             0x00000001
#define HwiDMAControl1Reg_RxSegment0Ready_Range             0x00000001
#define HwiDMAControl1Reg_RxSegment1Ready_Range             0x00000001

#define HwiDMAStatusReg_TxSegmentIndication                 0x00000001
#define HwiDMAStatusReg_RxSegmentIndication                 0x00000004

#define HwiDMAStatusReg_TxSegmentIndication_Shift           (0)
#define HwiDMAStatusReg_RxSegmentIndication_Shift           (2)

#define HwiDMAStatusReg_TxSegmentIndication_Range           0x00000001
#define HwiDMAStatusReg_RxSegmentIndication_Range           0x00000001

#define HwiDMAInterruptEnableReg_TxSegment                  0x00000001
#define HwiDMAInterruptEnableReg_RxSegment                  0x00000002
#define HwiDMAInterruptEnableReg_ModemStatus                0x00000004
#define HwiDMAInterruptEnableReg_RxSegmentOverrun           0x00000008
#define HwiDMAInterruptEnableReg_UARTOverrun                0x00000010

#define HwiDMAInterruptEnableReg_TxSegment_Shift            (0)
#define HwiDMAInterruptEnableReg_RxSegment_Shift            (1)
#define HwiDMAInterruptEnableReg_ModemStatus_Shift          (2)
#define HwiDMAInterruptEnableReg_RxSegmentOverrun_Shift     (3)
#define HwiDMAInterruptEnableReg_UARTOverrun_Shift          (4)

#define HwiDMAInterruptEnableReg_TxSegment_Range            0x00000001
#define HwiDMAInterruptEnableReg_RxSegment_Range            0x00000001
#define HwiDMAInterruptEnableReg_ModemStatus_Range          0x00000001
#define HwiDMAInterruptEnableReg_RxSegmentOverrun_Range     0x00000001
#define HwiDMAInterruptEnableReg_UARTOverrun_Range          0x00000001

#define HwiDMAInterruptStatusReg_TxSegment0                 0x00000001
#define HwiDMAInterruptStatusReg_TxSegment1                 0x00000002
#define HwiDMAInterruptStatusReg_RxSegment0                 0x00000004
#define HwiDMAInterruptStatusReg_RxSegment1                 0x00000008
#define HwiDMAInterruptStatusReg_ModemStatus                0x00000040
#define HwiDMAInterruptStatusReg_RxSegmentOverrun           0x00000080
#define HwiDMAInterruptStatusReg_UARTOverrun                0x00000100
#define HwiDMAInterruptStatusReg_Rx0Ready                   0x00010000
#define HwiDMAInterruptStatusReg_Rx0LineError               0x00020000
#define HwiDMAInterruptStatusReg_Rx0Timeout                 0x00040000
#define HwiDMAInterruptStatusReg_Rx1Ready                   0x00100000
#define HwiDMAInterruptStatusReg_Rx1LineError               0x00200000
#define HwiDMAInterruptStatusReg_Rx1Timeout                 0x00400000

#define HwiDMAInterruptStatusReg_TxSegment0_Shift           (0)
#define HwiDMAInterruptStatusReg_TxSegment1_Shift           (1)
#define HwiDMAInterruptStatusReg_RxSegment0_Shift           (2)
#define HwiDMAInterruptStatusReg_RxSegment1_Shift           (3)
#define HwiDMAInterruptStatusReg_ModemStatus_Shift          (6)
#define HwiDMAInterruptStatusReg_RxSegmentOverrun_Shift     (7)
#define HwiDMAInterruptStatusReg_UARTOverrun_Shift          (8)
#define HwiDMAInterruptStatusReg_Rx0Ready_Shift             (16)
#define HwiDMAInterruptStatusReg_Rx0LineError_Shift         (17)
#define HwiDMAInterruptStatusReg_Rx0Timeout_Shift           (18)
#define HwiDMAInterruptStatusReg_Rx1Ready_Shift             (20)
#define HwiDMAInterruptStatusReg_Rx1LineError_Shift         (21)
#define HwiDMAInterruptStatusReg_Rx1Timeout_Shift           (22)

#define HwiDMAInterruptStatusReg_TxSegment0_Range           0x00000001
#define HwiDMAInterruptStatusReg_TxSegment1_Range           0x00000001
#define HwiDMAInterruptStatusReg_RxSegment0_Range           0x00000001
#define HwiDMAInterruptStatusReg_RxSegment1_Range           0x00000001
#define HwiDMAInterruptStatusReg_ModemStatus_Range          0x00000001
#define HwiDMAInterruptStatusReg_RxSegmentOverrun_Range     0x00000001
#define HwiDMAInterruptStatusReg_UARTOverrun_Range          0x00000001
#define HwiDMAInterruptStatusReg_Rx0Ready_Range             0x00000001
#define HwiDMAInterruptStatusReg_Rx0LineError_Range         0x00000001
#define HwiDMAInterruptStatusReg_Rx0Timeout_Range           0x00000001
#define HwiDMAInterruptStatusReg_Rx1Ready_Range             0x00000001
#define HwiDMAInterruptStatusReg_Rx1LineError_Range         0x00000001
#define HwiDMAInterruptStatusReg_Rx1Timeout_Range           0x00000001



// references
// R
// W
// R0, always Read 0
// R/W
// R/W1P0
    // Software writes 1 to start the action, and then poll this bit to check if the controller has finished the action.
    // Read 1 means that the action is processing.
    // Read 0 means that the action is finished.


// R/W1P1
    // Software writes 1 to change the state, and then poll this bit to check if the controller has changed the state.
    // Read 1 means that the controller is in this state.
    // Read 0 means that the controller is not in this state or not yet.


// R/WP
    // Read 1 means that the controller is in A state.
    // Read 0 means that the controller is in B state.
    // Software can change state form A to B or B to A, and it should use the polling method to check if the controller has changed the state.
// R/W1C, Write 1 to clear


// HwiDivisorLatchLowReg
typedef struct _HwiDivisorLatchLowReg
{   
    ULONG    Data;       // R/W, 8bits
    
}HwiDivisorLatchLowReg, *PHwiDivisorLatchLowReg;

VOID
_SetHwiDivisorLatchLowReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDivisorLatchLowReg      pHwiDivisorLatchLowReg
    );

VOID
_GetHwiDivisorLatchLowReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDivisorLatchLowReg      pHwiDivisorLatchLowReg
    );

VOID
_ShowHwiDivisorLatchLowReg(
    IN      PHwiDivisorLatchLowReg      pHwiDivisorLatchLowReg
    );


// HwiDivisorLatchHighReg
typedef struct _HwiDivisorLatchHighReg
{   
    ULONG   Data;       // R/W, 8bits
    
}HwiDivisorLatchHighReg, *PHwiDivisorLatchHighReg;

VOID
_SetHwiDivisorLatchHighReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDivisorLatchHighReg     pHwiDivisorLatchHighReg
    );

VOID
_GetHwiDivisorLatchHighReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDivisorLatchHighReg     pHwiDivisorLatchHighReg
    );

VOID
_ShowHwiDivisorLatchHighReg(
    IN      PHwiDivisorLatchHighReg     pHwiDivisorLatchHighReg
    );

// HwiReceiverBufferReg
typedef struct _HwiReceiverBufferReg
{   
    ULONG   Data;       // R, 8bits
    
}HwiReceiverBufferReg, *PHwiReceiverBufferReg;

VOID
_GetHwiReceiverBufferReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiReceiverBufferReg       pHwiReceiverBufferReg
    );

VOID
_ShowHwiReceiverBufferReg(
    IN      PHwiReceiverBufferReg       pHwiReceiverBufferReg
    );


// HwiTransmitterHoldingReg
typedef struct _HwiTransmitterHoldingReg
{   
    ULONG   Data;       // W, 8bits
    
}HwiTransmitterHoldingReg, *PHwiTransmitterHoldingReg;

VOID
_SetHwiTransmitterHoldingReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiTransmitterHoldingReg   pHwiTransmitterHoldingReg
    );


// HwiInterruptEnableReg
typedef struct _HwiInterruptEnableReg
{   
    ULONG   ReceivedDataAvailable;      // R/W, 1bit, be cleard by a read to ReceiverBufferReg
    ULONG   TransmitterHoldingEmpty;    // R/W, 1bit, be cleard by a read to InterruptIdentificationReg
    ULONG   LineStatus;                 // R/W, 1bit, be cleard by a read to LineStatusReg
                                            // Overrun Error, Parity Error, Framing Error, BreakSignal
    ULONG   ModemStatus;                // R/W, 1bit, be cleard by a read to ModemStatusReg
    
}HwiInterruptEnableReg, *PHwiInterruptEnableReg;

VOID
_SetHwiInterruptEnableReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiInterruptEnableReg      pHwiInterruptEnableReg
    );

VOID
_GetHwiInterruptEnableReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiInterruptEnableReg      pHwiInterruptEnableReg
    );

VOID
_ShowHwiInterruptEnableReg(
    IN      PHwiInterruptEnableReg      pHwiInterruptEnableReg
    );


// HwiInterruptIdentificationReg
typedef struct _HwiInterruptIdentificationReg
{   
    ULONG   NoPending;      // R, 1bit
    ULONG   ID;             // R, 3bits, See EUARTInterruptID in EUARTDef.h
    
}HwiInterruptIdentificationReg, *PHwiInterruptIdentificationReg;

VOID
_GetHwiInterruptIdentificationReg(
    IN      PMappedBusAddress               hMappedRegisters,
        OUT PHwiInterruptIdentificationReg  pHwiInterruptIdentificationReg
    );

VOID
_ShowHwiInterruptIdentificationReg(
    IN      PHwiInterruptIdentificationReg  pHwiInterruptIdentificationReg
    );

// HwiFIFOControlReg
typedef struct _HwiFIFOControlReg
{   
    ULONG   FIFOEnable;             // W, 1bit
    ULONG   RxFIFOReset;            // W, 1bit
    ULONG   TxFIFOReset;            // W, 1bit
    ULONG   RxFIFOTriggerLevel;     // W, 2bits, See EUARTRxFIFOTriggerLevel in EUARTDef.h
    
}HwiFIFOControlReg, *PHwiFIFOControlReg;

VOID
_SetHwiFIFOControlReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiFIFOControlReg          pHwiFIFOControlReg
    );
    

// HwiLineControlReg
typedef struct _HwiLineControlReg
{   
    ULONG   WordLengthSelect;       // R/W, 2bits, See EUARTWordLengthSelect in EUARTDef.h
    ULONG   StopBitsSelect;         // R/W, 1bits, See EUARTStopBitsSelect in EUARTDef.h
    ULONG   ParityEnable;           // R/W, 1bit
    ULONG   ParitySelect;           // R/W, 2bits, See EUARTParitySelect in EUARTDef.h
    ULONG   TransmitBreak;          // R/W, 1bit, transmit a break condition until setting this bit to 0
    ULONG   DivisorLatchAccess;     // R/W, 1bit
    
}HwiLineControlReg, *PHwiLineControlReg;

VOID
_SetHwiLineControlReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiLineControlReg          pHwiLineControlReg
    );

VOID
_GetHwiLineControlReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiLineControlReg          pHwiLineControlReg
    );

VOID
_ShowHwiLineControlReg(
    IN      PHwiLineControlReg          pHwiLineControlReg
    );


// HwiModemControlReg
typedef struct _HwiModemControlReg
{   
    ULONG   DTRPin;             // R/W, 1bit, setting 1 to force pin to low
    ULONG   RTSPin;             // R/W, 1bit, setting 1 to force pin to low
    ULONG   Out1Pin;
    ULONG   Out2Pin;
    ULONG   LoopbackEnable;     // R/W, 1bit
    
}HwiModemControlReg, *PHwiModemControlReg;

VOID
_SetHwiModemControlReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiModemControlReg         pHwiModemControlReg
    );

VOID
_GetHwiModemControlReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiModemControlReg         pHwiModemControlReg
    );
    
VOID
_ShowHwiModemControlReg(
    IN      PHwiModemControlReg         pHwiModemControlReg
    );


// HwiLineStatusReg
typedef struct _HwiLineStatusReg
{   
    ULONG   DataReady;                  // R, 1bit
    ULONG   OverrunError;               // R, 1bit
    ULONG   ParityError;                // R, 1bit
    ULONG   FamingError;                // R, 1bit
    ULONG   BreakSignal;                // R, 1bit
    ULONG   TransmitterHodingEmpty;     // R, 1bit
    ULONG   TransmitterEmpty;           // R, 1bit
    ULONG   ErrorInRxFIFO;              // R, 1bit
    
}HwiLineStatusReg, *PHwiLineStatusReg;

VOID
_GetHwiLineStatusReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiLineStatusReg           pHwiLineStatusReg
    );

VOID
_ShowHwiLineStatusReg(
    IN      PHwiLineStatusReg           pHwiLineStatusReg
    );


// HwiModemStatusReg
typedef struct _HwiModemStatusReg
{   
    ULONG   CTSChange;  // R, 1bit
    ULONG   DSRChange;  // R, 1bit
    ULONG   RIChange;   // R, 1bit
    ULONG   DCDChange;  // R, 1bit
    ULONG   CTS;        // R, 1bit
    ULONG   DSR;        // R, 1bit
    ULONG   RI;         // R, 1bit
    ULONG   DCD;        // R, 1bit
    
}HwiModemStatusReg, *PHwiModemStatusReg;

VOID
_GetHwiModemStatusReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiModemStatusReg          pHwiModemStatusReg
    );

VOID
_ShowHwiModemStatusReg(
    IN      PHwiModemStatusReg          pHwiModemStatusReg
    );


// HwiScratchpadReg
typedef struct _HwiScratchpadReg
{   
    ULONG   Data;       // R/W, 8bits
    
}HwiScratchpadReg, *PHwiScratchpadReg;

VOID
_SetHwiScratchpadReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiScratchpadReg           pHwiScratchpadReg
    );

VOID
_GetHwiScratchpadReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiScratchpadReg           pHwiScratchpadReg
    );

VOID
_ShowHwiScratchpadReg(
    IN      PHwiScratchpadReg           pHwiScratchpadReg
    );


// HwiDMAControl0Reg
typedef struct _HwiDMAControl0Reg
{   
    ULONG   DMAEnable;              // R/W, 1bit
    ULONG   HardReset;              // R/W, 1bit
    ULONG   RxSegmentTriggerLevel;  // R/W, 3bit
    
    ULONG   DebugBit;               // R/W, 1bit
    
}HwiDMAControl0Reg, *PHwiDMAControl0Reg;

VOID
_SetHwiDMAControl0Reg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMAControl0Reg          pHwiDMAControl0Reg
    );

VOID
_GetHwiDMAControl0Reg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMAControl0Reg          pHwiDMAControl0Reg
    );


// HwiDMAControl1Reg
typedef struct _HwiDMAControl1Reg
{   
    ULONG   TxSegment0Ready;        // R/W1, 1bit
    ULONG   TxSegment1Ready;        // R/W1, 1bit
    ULONG   RxSegment0Ready;        // R/W1, 1bit
    ULONG   RxSegment1Ready;        // R/W1, 1bit
    
}HwiDMAControl1Reg, *PHwiDMAControl1Reg;

VOID
_SetHwiDMAControl1Reg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMAControl1Reg          pHwiDMAControl1Reg
    );

VOID
_GetHwiDMAControl1Reg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMAControl1Reg          pHwiDMAControl1Reg
    );


// HwiDMAStatusReg
typedef struct _HwiDMAStatusReg
{   
    ULONG   TxSegmentIndication;    // R, 1bit
    ULONG   RxSegmentIndication;    // R, 1bit
    
}HwiDMAStatusReg, *PHwiDMAStatusReg;

VOID
_GetHwiDMAStatusReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMAStatusReg            pHwiDMAStatusReg
    );


// HwiDMATxBufferAddressReg
typedef struct _HwiDMATxBufferAddressReg
{   
    ULONG   Address32bit;       // R/W, 32bit
    
}HwiDMATxBufferAddressReg, *PHwiDMATxBufferAddressReg;

VOID
_SetHwiDMATxBufferAddressReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMATxBufferAddressReg   pHwiDMATxBufferAddressReg
    );

VOID
_GetHwiDMATxBufferAddressReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMATxBufferAddressReg   pHwiDMATxBufferAddressReg
    );


// HwiDMARxBufferAddressReg
typedef struct _HwiDMARxBufferAddressReg
{   
    ULONG   Address32bit;       // R/W, 32bit
    
}HwiDMARxBufferAddressReg, *PHwiDMARxBufferAddressReg;

VOID
_SetHwiDMARxBufferAddressReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMARxBufferAddressReg   pHwiDMARxBufferAddressReg
    );

VOID
_GetHwiDMARxBufferAddressReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMARxBufferAddressReg   pHwiDMARxBufferAddressReg
    );


// HwiDMAInterruptEnableReg
typedef struct _HwiDMAInterruptEnableReg
{   
    ULONG   TxSegment;          // R/W, 1bit
    ULONG   RxSegment;          // R/W, 1bit
    ULONG   ModemStatus;        // R/W, 1bit
    ULONG   RxSegmentOverrun;   // R/W, 1bit
    ULONG   UARTOverrun;        // R/W, 1bit
    
}HwiDMAInterruptEnableReg, *PHwiDMAInterruptEnableReg;

VOID
_SetHwiDMAInterruptEnableReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMAInterruptEnableReg   pHwiDMAInterruptEnableReg
    );

VOID
_GetHwiDMAInterruptEnableReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMAInterruptEnableReg   pHwiDMAInterruptEnableReg
    );


// HwiDMAInterruptStatusReg
typedef struct _HwiDMAInterruptStatusReg
{   
    ULONG   TxSegment0;         // R/W1C, 1bit
    ULONG   TxSegment1;         // R/W1C, 1bit
    ULONG   RxSegment0;         // R/W1C, 1bit
    ULONG   RxSegment1;         // R/W1C, 1bit
    ULONG   ModemStatus;        // R/W1C, 1bit
    ULONG   RxSegmentOverrun;   // R/W1C, 1bit
    ULONG   UARTOverrun;        // R/W1C, 1bit
    
    ULONG   Rx0Ready;           // R, 1bit
    ULONG   Rx0LineError;       // R, 1bit
    ULONG   Rx0Timeout;         // R, 1bit
    
    ULONG   Rx1Ready;           // R, 1bit
    ULONG   Rx1LineError;       // R, 1bit
    ULONG   Rx1Timeout;         // R, 1bit
    
}HwiDMAInterruptStatusReg, *PHwiDMAInterruptStatusReg;

VOID
_SetHwiDMAInterruptStatusReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMAInterruptStatusReg   pHwiDMAInterruptStatusReg
    );

VOID
_GetHwiDMAInterruptStatusReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMAInterruptStatusReg   pHwiDMAInterruptStatusReg
    );


// HwiDMATx0DataLengthReg
typedef struct _HwiDMATx0DataLengthReg
{   
    ULONG   DataLength;         // R, 8bit
    
}HwiDMATx0DataLengthReg, *PHwiDMATx0DataLengthReg;


VOID
_SetHwiDMATx0DataLengthReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMATx0DataLengthReg     pHwiDMATx0DataLengthReg
    );


// HwiDMATx1DataLengthReg
typedef struct _HwiDMATx1DataLengthReg
{   
    ULONG   DataLength;         // R, 8bit
    
}HwiDMATx1DataLengthReg, *PHwiDMATx1DataLengthReg;


VOID
_SetHwiDMATx1DataLengthReg(
    IN      PMappedBusAddress           hMappedRegisters,
    IN      PHwiDMATx1DataLengthReg     pHwiDMATx1DataLengthReg
    );


// HwiDMARx0DataCountReg
typedef struct _HwiDMARx0DataCountReg
{   
    ULONG   DataCount;         // R, 8bit
    
}HwiDMARx0DataCountReg, *PHwiDMARx0DataCountReg;


VOID
_GetHwiDMARx0DataCountReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMARx0DataCountReg     pHwiDMARx0DataCountReg
    );
    

// HwiDMARx1DataCountReg
typedef struct _HwiDMARx1DataCountReg
{   
    ULONG   DataCount;         // R, 8bit
    
}HwiDMARx1DataCountReg, *PHwiDMARx1DataCountReg;


VOID
_GetHwiDMARx1DataCountReg(
    IN      PMappedBusAddress           hMappedRegisters,
        OUT PHwiDMARx1DataCountReg     pHwiDMARx1DataCountReg
    );
    
#endif
