#ifdef CO_30_DIAGS

#define SCRATCH_REG_PORT                (0x0b)

/************** INCLUDE FILES ****************************/
#include <stdio.h>
//#include <vxWorks.h>
//#include "apposmacro.h"
#include "diags_defines.h"
#include "dapi.h"

/************** LOCAL MACROS *****************************/
#define HIC_RDY_TIMEOUT_PORT (0xC)    // port address
#define HIC_RDY_TIMEOUT_ENABLE (0x80) // timeout enable bit [7]
#define HIC_RDY_TIMEOUT_STATUS (0x40) // timeout status bit [6]
#define BYTE_TIMEOUT_VAL_MSB_6_BITS (0x01) // x256 CO core cycles

/************** GLOBAL VARIABLES *************************/
//static int gHicDmaInitialized[3] = {0,0,0};
static bmeIdStruct_t allBmeIds[NUM_BME_IDS] = {VALID_BME_IDS};

/************** EXTERN FUNCTIONS AND VARIABLES ***********/
extern tBmeStruct  	BmeStruct[IPOS_MAX_BME+1]; /* BME objects for direct API */
int testPIORead1 (int BmeNum, unsigned long addr);
void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data);


/************** LOCAL FUNCTION PROTOTYPES ****************/
void HicScratchReg_Write(tBmeStruct *bmeStruct, BYTE statusMask);
BYTE HicScratchReg_Read(tBmeStruct *bmeStruct);

/********************************************************/
/*              LOCAL FUNCTION DEFINITIONS              */
/********************************************************/

/********************************************************/
/*            EXPORTED FUNCTION DEFINITIONS             */
/********************************************************/
int bup_check_bme_id (int bmeNum)
{
	int stat = -1; int i;
	int ReadData;

	ReadData = testPIORead1 (bmeNum, PIO_BID(0));

    for (i = 0; i < NUM_BME_IDS; i++)
    {
        if (ReadData == allBmeIds[i].bmeID)
        {
            stat = 0;

            DBG1 (("Bme %d: read back %s ID: 0x%x\n", bmeNum,
                    allBmeIds[i].bmeName, ReadData));
            break;
        }
    }
    if (i == NUM_BME_IDS)
    {
		stat = -1;
		DBG0(("Bme %d: Test FAILED, read back BME ID: 0x%x\n",bmeNum, ReadData))
    }
	return stat;
}

int HicTimeoutTest (int bmeNum)
{
    BYTE RdyCounter;
	BYTE *baseAddr;
    UINT32 data1;

    /* HIC timeout port test (bus monitor):
       - program a timeout value
       - read back the programmed value
       - issue a HIC PIO read
       - read the timeout counter value */
    /* NOTE: This test is just a r/w test. It doesnt test the timeout feature */

	baseAddr = (BYTE *)(&BmeStruct[bmeNum].BMEbaseAddr);

/* set the HIC Timeout port with the uppper 6 bits of 14 bit counter, and enable feature */
    RdyCounter = BYTE_TIMEOUT_VAL_MSB_6_BITS | HIC_RDY_TIMEOUT_ENABLE;
    DBG2( ("Configuring HIC_RDY_TIMEOUT port with TO_CNT = "));
    writeControlPort (baseAddr, (HIC_RDY_TIMEOUT_PORT), RdyCounter);
    DBG2( ("0x%x CO core cycles\n", (RdyCounter & 0x3F) * 0x100));

	data1 = testPIORead1 (bmeNum, HIC_PIO_TEST_MEM_ADDR);

    RdyCounter = 0;
    DBG2( ("reading from the HIC_RDY_TIMEOUT port: "));
    readControlPort (baseAddr, (HIC_RDY_TIMEOUT_PORT), RdyCounter);
    DBG2( ("0x%x\n", RdyCounter));

    if (RdyCounter == (BYTE_TIMEOUT_VAL_MSB_6_BITS | HIC_RDY_TIMEOUT_ENABLE))
    {
        DBG1(("Bme %d: HIC Timeout port test passed\n", bmeNum))
        return 0;
    }
    else
    {
        DBG0(("Bme %d: HIC Timeout port test FAILED\n", bmeNum))
        return -1;
    }
}

#ifdef CO_20
int HicDMARWTest (int bmeNum)
{
    BYTE wrDmaData[0x100];
    int dmaDone = FALSE, i;

    if (!gHicDmaInitialized[bmeNum])
    {
        InitDmaChannel15 (&BmeStruct[bmeNum]);
        gHicDmaInitialized[bmeNum] = 1;
    }

    for (i = 0; i < 0x100; i++)
        wrDmaData[i] = i+1;

    BmeStruct[bmeNum].fifoStatus = FIFO_WRITE_IN_PROGRESS;
    bmeWrMemory (&BmeStruct[bmeNum], HIC_DMA_TEST_MEM_ADDR, wrDmaData, 0x100);

    for (i = 0; i < 0x100; i++)
        wrDmaData[i] = 0;

    i = 0;
    while ((dmaDone = pollDmaDone (&BmeStruct[bmeNum])) != TRUE && i < 100)
    {
        iposTaskDelay(10);
        i++;
    }
    if (dmaDone != TRUE)
    {
        DBG0(("Bme %d: HIC DMA test FAILED: Write timeout\n", bmeNum))
        return -1;
    }

    BmeStruct[bmeNum].fifoStatus = FIFO_READ_IN_PROGRESS;
    bmeTrMemory (&BmeStruct[bmeNum], HIC_DMA_TEST_MEM_ADDR, 0x100);

    i = 0;
    while ((dmaDone = pollDmaDone (&BmeStruct[bmeNum])) != TRUE && i < 100)
    {
        iposTaskDelay(10);
        i++;
    }
    if (dmaDone != TRUE)
    {
        DBG0(("Bme %d: HIC DMA test FAILED: Read timeout\n", bmeNum))
        return -2;
    }

    BmeStruct[bmeNum].dataLen = 0x100;
    bmeRdMemory (&BmeStruct[bmeNum], wrDmaData);

    for (i = 0; i < 0x100; i++)
    {
        if (wrDmaData[i] != (UINT8)(i+1))
        {
            DBG0(("Bme %d: HIC DMA test FAILED: Data mismatch\n", bmeNum))
            return -3;
        }
    }

    DBG1(("Bme %d: HIC DMA test passed\n", bmeNum))
    return 0;
}
#endif

int HicPIOBulkRWTest (int bmeNum)
{
    UINT32 destAddr = HIC_PIO_TEST_MEM_ADDR;
    UINT32 srcAddr  = HIC_PIO_TEST_MEM_ADDR;
    UINT32 trfrData[10] = {0x3454ABCD, 0xBDCE0342, 0x23BDC451, 0xDABE3495, 0x456789CD,
                           0x1029BCE2, 0x232B3453, 0xABCDE123, 0xFCDE2345, 0xA43BE9BC};
    UINT32 readData[10] = {0,0,0,0,0,0,0,0,0,0};
    int i;

    bmePioBulkWrite (&BmeStruct[bmeNum], destAddr, (BYTE *)trfrData, 10*4);
    bmePioBulkRead  (&BmeStruct[bmeNum], srcAddr , (BYTE *)readData, 10*4);

    for (i = 0; i < 10; i++)
        if (readData[i] != trfrData[i])
        {
            DBG0(("Bme %d: HIC PIO Read/Write with address auto-increment test FAILED\n", bmeNum))
            return (-1);
        }

    DBG1(("Bme %d: HIC PIO address auto-increment test passed\n", bmeNum))
    return 0;
}

int bup_scratch_reg_rw (int bmeNum)
{
    tBmeStruct *pBme;
    unsigned int rd_val,wr_val;

    pBme = &BmeStruct[bmeNum];
                  
    for(wr_val = 0; wr_val < 256;wr_val++)
    {
       HicScratchReg_Write (pBme ,wr_val);

       BUP_DELAY_MS(1);

       rd_val = HicScratchReg_Read (pBme);
       if(wr_val != rd_val)
       {
           DBG0(("Bme %d: HIC scratch register r/w test FAILED: wr_val:%d, rd_val:%d\n", bmeNum, wr_val,rd_val))
           return -1;
       } else {
           DBG2(("HIC scratch reg r/w Pass: wr_val:%d,rd_val:%d\n", wr_val,rd_val))
       }
    }
    DBG1(("Bme %d: HIC Scratch Reg test passed\n", bmeNum))
    return 0;
}


void HicScratchReg_Write(tBmeStruct *bmeStruct, BYTE statusMask)
{
    BYTE *baseAddr;

    /* get the base address of the BME chip */
    baseAddr = (BYTE *)bmeStruct->BMEbaseAddr;


    /* Write to HOST ACK Port to clear BME FIFO/interrupt status. */
    writeControlPort (baseAddr, SCRATCH_REG_PORT, statusMask);


    return;
}

BYTE HicScratchReg_Read(tBmeStruct *bmeStruct)
{
    BYTE *baseAddr;
    BYTE readVal;
    /* get the base address of the BME chip */
    baseAddr = (BYTE *)bmeStruct->BMEbaseAddr;


    /* Write to HOST ACK Port to clear BME FIFO/interrupt status. */
    readControlPort (baseAddr, SCRATCH_REG_PORT, readVal);

    return(readVal);
}

#endif //CO_30_DIAGS
