// =============================================================================
//                           COPYRIGHT NOTICE
// Copyright 2003 (c) Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// This confidential and proprietary software may be used only as authorised by
// a licensing agreement from Lattice Semiconductor Corporation.
// The entire notice above must be reproduced on all authorized copies and
// copies may only be made to the extent permitted by a licensing agreement from
// Lattice Semiconductor Corporation.
//
// Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
// 5555 NE Moore Court                            408-826-6000 (other locations)
// Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
// U.S.A                                   email: techsupport@latticesemi.com
// =============================================================================
//                         FILE DETAILS
// Project          : PCI Core SDK
// File             : pcicore.h
// Title            : 
// Dependencies     : 
// Description      : 
//                   
// =============================================================================
//                        REVISION HISTORY
// Version          : 1.0
// Mod. Date        : March 17, 2006
// Changes Made     : 
//
// ============================================================================= 

#ifndef __PCICORE_H__
#define __PCICORE_H__

#ifdef __cplusplus
extern "C" {
#endif

#define DMA_READ       0
#define DMA_WRITE      1

// ============================================================================= 
//
// Error Code
//
// ============================================================================= 
#define PCICORE_SUCCESS                      0
#define PCICORE_DEVICE_NO_FOUND              1
#define PCICORE_INVALID_PARAMETER            2
#define PCICORE_NO_ENOUGH_MEMORY             3
#define PCICORE_IOCTL_FAIL                   4
#define PCICORE_INITIALIZE_FAIL              5
#define PCICORE_REGISTER_ISR_FAIL            6
#define PCICORE_DEVICE_NO_INITIALIZE         7
#define PCICORE_INVALID_OPERATION            8
#define PCICORE_REGISTER_NO_INITIALIZE       9
#define PCICORE_DMA_OPERATION_FAIL           10
#define PCICORE_DMA_NO_DOING                 11

// ============================================================================= 
//
// Register 
//
// ============================================================================= 
#define BAR_MAX_NUM                6
#define BAR_SPACE_IO               0
#define BAR_SPACE_MEMORY           1

#define REG_SPACE_IO               0
#define REG_SPACE_MEMORY           1

#define REG_WIDTH_DEFAULT          0
#define REG_WIDTH_8                1
#define REG_WIDTH_16               2
#define REG_WIDTH_32               3

#define REG_WRITE_READ             0
#define REG_READ_ONLY              1
#define REG_WRITE_ONLY             2

#define BAR_SPACE_IO               0
#define BAR_SPACE_MEMORY           1

#define REG_MAX_NUM                8 
#define REG_INTR_STATUS            0
#define REG_INTR_ACKNOWLEDGE       1
#define REG_INTR_MASK              2
#define REG_DMA_ADDRESS            3
#define REG_DMA_LENGTH             4
#define REG_DMA_DIRECTION          5
#define REG_DMA_CONTROL            6
#define REG_DMA_STATUS             7

#define REG_SET      ((1 << REG_MAX_NUM) - 1)
#define REG_INTR_SET ((1 << REG_INTR_STATUS) +      \
                      (1 << REG_INTR_ACKNOWLEDGE) + \
                      (1 << REG_INTR_MASK))

// ============================================================================= 
//
// typedef
//
// =============================================================================
typedef struct _BAR_INFO
{
    ULONG              dwSize;    
    ULONG              dwFlag;
}BAR_INFO, PBAR_INFO;

typedef struct _DEVICE_INFO
{
    ULONG              dwBarNum;
    BAR_INFO           BarInfo[6];
}DEVICE_INFO, *PDEVICE_INFO;

typedef void (*pAppISR)(void* data);

// ============================================================================= 
//
// Read the data from the PCI config space
//
// ============================================================================= 
#define ReadConfigB(devID, offset, output)  \
        ReadDataFromConfig(devID, offset, (unsigned char *)(output), 1)

#define ReadConfigW(devID, offset, output)  \
        ReadDataFromConfig(devID, offset, (unsigned char *)(output), 2)

#define ReadConfigD(devID, offset, output)  \
        ReadDataFromConfig(devID, offset, (unsigned char *)(output), 4)

// ============================================================================= 
//
// Write the data to the PCI config space
//
// ============================================================================= 
#define WriteConfigB(devID, offset, input)  \
        WriteDataToConfig(devID, offset, (unsigned char *)(input), 1)

#define WriteConfigW(devID, offset, input)  \
        WriteDataToConfig(devID, offset, (unsigned char *)(input), 2)

#define WriteConfigD(devID, offset, input)  \
        WriteDataToConfig(devID, offset, (unsigned char *)(input), 4)

// ============================================================================= 
//
// Read the data from the memory space or the I/O space
//
// ============================================================================= 
#define ReadBarB(devID, barID, offset, output) \
        ReadDataFromBar(devID, barID, offset, (unsigned char *)(output), 1)

#define ReadBarW(devID, barID, offset, output) \
        ReadDataFromBar(devID, barID, offset, (unsigned char *)(output), 2)

#define ReadBarD(devID, barID, offset, output) \
        ReadDataFromBar(devID, barID, offset, (unsigned char *)(output), 4)

// ============================================================================= 
//
// Write the data to the memory space or the I/O space
//
// ============================================================================= 
#define WriteBarB(devID, barID, offset, input) \
        WriteDataToBar(devID, barID, offset, (unsigned char *)(input), 1)

#define WriteBarW(devID, barID, offset, input) \
        WriteDataToBar(devID, barID, offset, (unsigned char *)(input), 2)

#define WriteBarD(devID, barID, offset, input) \
        WriteDataToBar(devID, barID, offset, (unsigned char *)(input), 4)

// ============================================================================= 
//
// Config the register
//
// ============================================================================= 
#define SetIntrStatusReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)    \
        ConfigRegister(devID, REG_INTR_STATUS, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetIntrAckReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)       \
        ConfigRegister(devID, REG_INTR_ACKNOWLEDGE, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetIntrMaskReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)      \
        ConfigRegister(devID, REG_INTR_MASK, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetDmaAddrReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)       \
        ConfigRegister(devID, REG_DMA_ADDRESS, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetDmaLenReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)        \
        ConfigRegister(devID, REG_DMA_LENGTH, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetDmaDirectionReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)  \
        ConfigRegister(devID, REG_DMA_DIRECTION, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetDmaCtrlReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart)       \
        ConfigRegister(devID, REG_DMA_CONTROL, barID, offset, regWidth, regAccess, bitWidth, bitStart);

#define SetDmaStatusReg(devID, barID, offset, regWidth, regAccess, bitWidth, bitStart) \
        ConfigRegister(devID, REG_DMA_STATUS, barID, offset, regWidth, regAccess, bitWidth, bitStart);

int ReadDataFromConfig(
    unsigned int      devID, 
    unsigned int      offset, 
    unsigned char    *output, 
    unsigned int      length
);

int WriteDataToConfig(
    unsigned int      devID, 
    unsigned int      offset, 
    unsigned char    *input, 
    unsigned int      length
);

int ReadDataFromBar(
    unsigned int      devID, 
    unsigned int      barID, 
    unsigned int      offset, 
    unsigned char    *output, 
    unsigned int      length
);

int WriteDataToBar(
    unsigned int      devID, 
    unsigned int      barID, 
    unsigned int      offset, 
    unsigned char    *input, 
    unsigned int      length
);

int ConfigRegister(
    unsigned int      devID,
    unsigned int      regID,
    unsigned int      barID,
    unsigned int      offset,
    unsigned int      regWidth,
    unsigned int      regAccess,
    unsigned int      bitWidth,
    unsigned int      bitStart
);

int EnumDevice(
    void
);

int InitDevice(
    unsigned int      devID
);

int UninitDevice(
    unsigned int      devID
);

int RegISRForApp(
    unsigned int      devID,
    pAppISR           ai, 
    void             *data
);

int UnregISRForApp(
    unsigned int      devID
);

int DoDMA(
    unsigned int      devID,
    unsigned char    *buffer,
    unsigned int      length,
    unsigned int      direction
);

void DMADone(
    unsigned int     devID
);

int GetDeviceInfo(
    unsigned int         devID,
    PDEVICE_INFO         pdevinfo
);

#ifdef __cplusplus
}
#endif

#endif