/**************************************************************
$Workfile:   bmehwapi.c  $
***************************************************************
***************************************************************
**
**  Filename    : bmehwapi.c
**  Description : c source file defining the BME hardware APIs
**  Author      : jeya
**  Date        : 26 Feb 2001
**  Notes       :
**  References  : Host Interface Controller Block Definition Doc
                    prepared by Weiluo
**  Revision History :
**
****************************************************************/
/***************************************************************
**
** FIRMWARE, Copyright (C) 2000-2002
** Ikanos Communication, Fremont, CA
** All rights reserved.
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of
** Ikanos Communication
**
***************************************************************
$Revision: 1.1 $
$Date: 2006/10/16 04:34:51 $
**************************************************************/

/* #includes */
#include <stdio.h>
#include <string.h>

#include "dapi.h"
#include "apiosmacro.h"
#include "bsp.h"
#ifndef USE_VXWORKS /* IXDP425 */
#include <v2pthread.h>
#define EOS '\0'
#endif
#ifdef VTU_O

#ifdef CPE_40
#ifdef CO_40
#ifdef CO_50
  #include "coBME50Code.h"
#elif defined( CO_40)
  #include "coBME40Code.h"
#else
  #include "coBME30Code.h"
#endif
#endif




#elif defined( CO_20)

  #ifdef BUP_DIAGS
  #include "coBME20CodeDiags.h"
  #else
  #include "coBME20Code.h"
  #endif

#elif defined(P2CPE) || defined(P2CO)
  #include "coP2Code.h"
#elif defined(BME_CPE_20)
  #include "co20Code.h"
#else
  #include "coCode.h"
#endif
#elif defined(VTU_R)
#if defined(P2CPE) || defined(P2CO)
  #include "cpeP2Code.h"
#elif defined(CPE_50)
  #include "cpe50Code.h"
#elif defined(BME_CPE_20)
  #include "cpe20Code.h"
#else
  #include "cpeCode.h"
#endif
#endif

/* _BME_TEST_CODE_ */
/* #include "test.h" */

/* Note : these #includes to be included later */
/* #include "drv/multi/mdpm860Siu.h" */
/* #include "hsiMdpPro8xxT.h" */

/* Note : these definitions are temporary. to be removed later */
#define PD3     0x1000
#define PD4     0x0800
#define PD5     0x0400

/* Global Variables */
//BYTE msgRdyPending = FALSE;
BYTE writeBufCnt = 0;
BYTE readBufCnt = 0;
BYTE firstWrite = TRUE;
BYTE firstRead = TRUE;

BYTE BmeResetVecCode[BME_RESET_VEC_CODE_SIZE] = {
0x60, 0x00, 0x04, 0x00, 0xff,0x01,0x00,0xff/*0x70*/, 0x10, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00};
/*0x40,0x01,0xe9,0x9c,0x40,0x01,0x00,0x70,0x10,0xff,0xff,0x0a,0x00,0x00,0x00,0x00};*/

BYTE BmeResetVecCode2[56] = {
0x1,0x1,0x3,0x1,0x1,0x47 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0
 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0
 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0
 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x3,0x2,0x1};

#if defined (CO_20) || defined (CPE_40)
#define HIC_PIO_AUTO_INCR
#endif

int wrCount = 0;
int rdCount = 0;

/* function definitions */
HWAPI_RET_VAL bmeVerifyWriteCode (tBmeStruct *bmeStruct, UINT32 codeDnldAddr, UINT32 codeLen, BYTE *BmeCodeArrayPtr);
HWAPI_RET_VAL bmeVerifyCodeDnld (tBmeStruct *bmeStruct);

void iposDelay (void);
void bmeRelCpu (tBmeStruct *pBme,unsigned char enable);
void setclk (tBmeStruct *pBme, int num);
extern void set_clkM (int which);
/* extern declarations */
extern void bmeHwResetApi (int BmeNum);
extern void setProdMode (unsigned char enable);
extern void relBmeCpu (unsigned char enable);
extern void relCpu (int BmeNum, unsigned char enable);
extern void fpgaHWReset (void);

extern void convertDataToEndianFormat (BYTE bDataSize, BYTE *bDataPtr);
extern BYTE HostCpuEndianType;

extern void rdDMARegs(void);
extern void InitSdramM (int x16, int OpenPage, int which);
extern int testPIORead1 (int BmeNum, unsigned long addr);

extern void HostFpgaWrite(BYTE boffset,BYTE bdata);
extern void iposPtmfReset(void);

#ifdef IK_EXTERN_PIO_WRITE
	extern void tpw (int BmeNum, unsigned long addr, unsigned long data);
	extern void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data);
#endif


#ifdef CPE_40_DIAGS
extern int diagsHoldCpuInReset;
#endif

#ifdef  BME_CPE_20
extern  void init_sdram_32clk();
extern  void init_sdram_16clk();
extern  void iniwrite(BYTE addr,BYTE data);
extern  char getSysInfo (char   *sysInfo);
#endif

void emuDelay( int loop_length )
{
	volatile int i;

	for (i=0; i<loop_length; i++);
}
#ifdef CPE_40_EMULATION
#define VERY_SHORT_DELAY(a)		emuDelay(a)
#else
#define VERY_SHORT_DELAY(a)
#endif
#if defined(CO_20_EMULATION_BOARD) || defined (CPE_40_EMULATION) || defined(CO_50_EMULATION_BOARD)
int bmeReleased = 0;
#endif


/********************************************************************************\
    Name       : InitDmaChannel15
    Purpose    : To initialize & program the BME DMA channel 15 for HIC interface

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     : void
\********************************************************************************/

void InitDmaChannel15 (tBmeStruct *bmeStruct)
{
#ifdef CPE_40
    bmeClrStatus (bmeStruct, CLR_MSG_RDY_IN_BME_DPRAM);
#else
    BYTE *baseAddr;
    UINT32 tempVal = 0;

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

    /* program DMA_ECR15 - Event Control Register */
    tempVal = 0x80000000; /* sw DMA request */
    bmePioWrite (bmeStruct, DMA_ECR(0, DMA_CH_15), (BYTE *)&tempVal);
    /* disable Interrupts if required */

#ifndef HOST_INTERRUPT
    bmeIntDisable (bmeStruct, ALL_INTERRUPTS);
#endif

    /*enableIRQ1();*/

    /* program DMA_CCR15 - Channel Control Register */
    writeControlPort(baseAddr,(DMA_REG_ADDR_PORT ), 0xe0);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x03);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);

#if defined(BME_CPE_20) || defined (CO_20)
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x1c);
#else
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x3c);
#endif

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_DMA_CCR_REG_WR_CMD);

    /* program DMA_SAR15 - Source Address Register */
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xe0);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x03);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);

#if defined(BME_CPE_20) || defined (CO_20)
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x9c);
#else
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xbc);
#endif

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_DMA_SAR_REG_WR_CMD);

    /* program DMA_DAR15 - Destination Address Register */
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xe0);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x03);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);

#if defined(BME_CPE_20) || defined (CO_20)
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xdc);
#else
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xfc);
#endif

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_DMA_DAR_REG_WR_CMD);

    /* program HIC_FIFO base addr */
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xc7);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_HIC_FIFO_ADDR_CMD);

    /* program DMA_CCR15 - Channel Control Register */
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xe0);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x03);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);
#if defined(BME_CPE_20) || defined (CO_20)
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x1c);
#else
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x3c);
#endif

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_DMA_CCR_REG_RD_CMD);

    /* program DMA_SAR15 - Source Address Register */
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xe0);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x03);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);

#if defined(BME_CPE_20) || defined (CO_20)
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x9c);
#else
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xbc);
#endif

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_DMA_SAR_REG_RD_CMD);

    /* program DMA_DAR15 - Destination Address Register */
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xe0);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x03);
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0x00);

#if defined(BME_CPE_20) || defined (CO_20)
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xdc);
#else
    writeControlPort(baseAddr, (DMA_REG_ADDR_PORT), 0xfc);
#endif

    writeControlPort(baseAddr, (COMMAND_PORT), UPD_DMA_DAR_REG_RD_CMD);

#endif /* CPE_40 */
}



/********************************************************************************\
    Name       : InitEMIConfig
    Purpose    : To initialize & program the BME EMI interface

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     : void
\********************************************************************************/

HWAPI_RET_VAL InitEMIConfig (tBmeStruct *bmeStruct)
{

#ifdef  BME_CPE_20

/* cpe_20 memory configration code */

    switch(bmeStruct->EMIConfig.memType)
    {
     printf("Fusiv EMI SDRAM %x\n",bmeStruct->EMIConfig.memType);
    case IPOS_BME_MEM_SDRAM32:

        init_sdram_32clk ();
        break;
    case IPOS_BME_MEM_SDRAM16:
        init_sdram_16clk ();
        break;
//  init_sdram_16clkby2 ();
    case IPOS_BME_MEM_SRAM:
#ifdef CPE_ATM
        init_sdram_16clk ();
#endif
        break;

    default:
        init_sdram_16clk ();
        break;
    }

  //  IK_PRINTF("EMI parameters: %d",bmeStruct->EMIConfig.memType);
    return((enum HWAPI_RET_VAL)1);
#elif defined CO_20
    InitSdramM(1,1,bmeStruct->BmeNum);
    return((enum HWAPI_RET_VAL)1);

#else
/* generic BME memory configuration code */

    unsigned long tempVal = 0;

    /* 3. program EMI (SRAM/SDRAM/SGRAM) interface */
    /* program EMI_MCR - Module Control Register */

    /* set EMI memory type */
    switch (bmeStruct->EMIConfig.memType)
    {
        case MEM_SRAM:
            tempVal |= EMI_MEM_SRAM;
            /* set SRAM memory size */
            switch (bmeStruct->EMIConfig.sramMemSize)
            {
                case SRAM_1MB:
                    tempVal |= EMI_SRAM_1MB;
                    break;

                case SRAM_2MB:
                    tempVal |= EMI_SRAM_2MB;
                    break;

                default:
/*                  EventLog("b%dp0 bmeSoftwareDnld Rv HWAPI_DNLD_FAILURE wrong EMI memory size"
                        ,bmeStruct->BmeNum);*/
                    return (HWAPI_DNLD_FAILURE);
            }
            break;

        case MEM_SDRAM:
            tempVal |= EMI_MEM_SDRAM;
            /* set SDRAM memory size */
            switch (bmeStruct->EMIConfig.sdramMemSize)
            {
                case SDRAM_16MB:
                    tempVal |= EMI_SDRAM_16MB;
                    break;

                case SDRAM_22MB:
                    tempVal |= EMI_SDRAM_22MB;
                    break;

                case SDRAM_8MB:
                    tempVal |= EMI_SDRAM_8MB;
                    break;

                default:
                    /*EventLog("b%dp0 bmeSoftwareDnld Rv HWAPI_DNLD_FAILURE: wrong EMI memory size"
                        ,bmeStruct->BmeNum);*/

                    return (HWAPI_DNLD_FAILURE);
            }

            /* set SDRAM CAS Latency period */
            switch (bmeStruct->EMIConfig.casLat)
            {
                case CAS_LAT_3_CLOCKS:
                    tempVal |= EMI_CAS_LAT_3_CLOCKS;
                    break;

                case CAS_LAT_2_CLOCKS:
                    tempVal |= EMI_CAS_LAT_2_CLOCKS;
                    break;

                default:
                    /*  EventLog("b%dp0 bmeSoftwareDnld Rv HWAPI_DNLD_FAILURE: wrong EMI CAS_LAT value"
                        ,bmeStruct->BmeNum);*/

                    return (HWAPI_DNLD_FAILURE);
            }

            /* set SDRAM RAS to CAS Delay period */
            switch (bmeStruct->EMIConfig.rcDel)
            {
                case RC_DEL_2_CLOCKS:
                    tempVal |= EMI_RC_DEL_2_CLOCKS;
                    break;

                case RC_DEL_3_CLOCKS:
                    tempVal |= EMI_RC_DEL_3_CLOCKS;
                    break;

                default:
                    IK_PRINTF ("\nwrong EMI RC_DEL value!!!!");
                    return (HWAPI_DNLD_FAILURE);
            }

            /* set SDRAM minimum row precharge time */
            switch (bmeStruct->EMIConfig.rowPre)
            {
                case ROW_PRE_2_CLOCKS:
                    tempVal |= EMI_ROW_PRE_2_CLOCKS;
                    break;

                case ROW_PRE_3_CLOCKS:
                    tempVal |= EMI_ROW_PRE_3_CLOCKS;
                    break;

                default:
                    IK_PRINTF ("\nwrong EMI ROW_PRE type!!!!");
                    return (HWAPI_DNLD_FAILURE);
            }

            /* set SDRAM minimum row active time */
            switch (bmeStruct->EMIConfig.rowAct)
            {
                case ROW_ACT_6_CLOCKS:
                    tempVal |= EMI_ROW_ACT_6_CLOCKS;
                    break;

                case ROW_ACT_7_CLOCKS:
                    tempVal |= EMI_ROW_ACT_7_CLOCKS;
                    break;

                default:
                    IK_PRINTF ("\nwrong EMI ROW_ACT type!!!!");
                    return (HWAPI_DNLD_FAILURE);
            }

            /* set SDRAM minimum row cycle time */
            switch (bmeStruct->EMIConfig.rowCyc)
            {
                case ROW_CYC_11_CLOCKS:
                    tempVal |= EMI_ROW_CYC_11_CLOCKS;
                    break;

                case ROW_CYC_10_CLOCKS:
                    tempVal |= EMI_ROW_CYC_10_CLOCKS;
                    break;

                default:
                    IK_PRINTF ("\nwrong EMI ROW_CYC type!!!!");
                    return (HWAPI_DNLD_FAILURE);
            }

            break;

        default:
            IK_PRINTF ("\nwrong EMI memory type!!!!");
            return (HWAPI_DNLD_FAILURE);
    }

    /* program EMI_MCR - Module Control Register */
    bmePioWrite (bmeStruct, EMI_MCR(0), (BYTE *)&tempVal);

    /* program EMI_RPR - SDRAM Refresh Period Register */
    if (bmeStruct->EMIConfig.memType == MEM_SDRAM)
    {
        tempVal = bmeStruct->EMIConfig.refPeriod;
        bmePioWrite (bmeStruct, EMI_RPR(bmeStruct->BMEbaseAddr), (BYTE *)&tempVal);
    }

    return((enum HWAPI_RET_VAL)1);
#endif
}

/********************************************************************************\
    Name       : bmeIntEnable
    Purpose    : To enable BME interrupt signals to the host processor.

    Parameters :
    no     Name         Type            Description
    --     ----         ----            -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. intrMask     BYTE           Interrupt mask

    Return     : void
\********************************************************************************/

void bmeIntEnable(tBmeStruct *bmeStruct, BYTE intrMask)
{

#ifdef HOST_INTERRUPT

    BYTE *baseAddr;
    BYTE tempIntrMask;

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

    /* Higher level APIs can call this function to change the host interrupt
       enable settings at any time.
       There are 2 interrupts that can be enabled.
       1.DMA write done.
       2.Message ready in DPRAM. */

    switch (intrMask)
    {
#ifndef CPE_40
        case DMA_WRITE_DONE_INTR:
            /* set MASK_EN[0] bit in DMA Control Port to enable DMA write done interrupt. */
            tempIntrMask = DMA_WRITE_DONE_INTR | UPD_DMA_WRITE_DONE_INTR;
            break;
#endif

        case MSG_RDY_IN_BME_DPRAM_INTR:
            /* set MASK_EN[1] bit in DMA Control Port to enable Message ready in DPRAM interrupt.*/
            tempIntrMask = MSG_RDY_IN_BME_DPRAM_INTR | UPD_MSG_RDY_IN_BME_DPRAM_INTR;
            break;

        case ALL_INTERRUPTS:
#ifndef CPE_40
            /* set MASK_EN[0] & MASK_EN[1] bits in DMA Control Port to enable both the interrupts */
            tempIntrMask = DMA_WRITE_DONE_INTR | MSG_RDY_IN_BME_DPRAM_INTR | UPD_DMA_WRITE_DONE_INTR | UPD_MSG_RDY_IN_BME_DPRAM_INTR;
#else
            tempIntrMask = MSG_RDY_IN_BME_DPRAM_INTR | UPD_MSG_RDY_IN_BME_DPRAM_INTR;
#endif
            break;

        default:
            IK_PRINTF ("\nwrong interrupt mask to enable.");
            return;
    }

    /* write the value to DMA Control Port */
    writeControlPort(baseAddr, (DMA_CTRL_PORT), tempIntrMask);

#ifdef _DEBUG_
/*  IK_PRINTF ("\nInterrupt value enabled is 0x%2x", tempIntrMask); */

#endif /* _DEBUG_ */
#else
	// Remove warning
	bmeStruct++;
#endif

}

/********************************************************************************\
    Name       : bmeIntDisable
    Purpose    : To disable BME interrupt signals to the host processor.

    Parameters :
    no     Name      Type          Description
    --     ----      ----          -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. intrMask     BYTE        Interrupt mask

    Return     : void
\********************************************************************************/

void bmeIntDisable(tBmeStruct *bmeStruct, BYTE intrMask)
{
    BYTE *baseAddr;
    BYTE   tempIntrMask;

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

    /* Higher level APIs can call this function to change the host interrupt disable settings at any time.
       There are 2 interrupts that can be disabled.
       1.DMA write done.
       2.Message ready in DPRAM. */

    switch (intrMask)
    {
#ifndef CPE_40
        case DMA_WRITE_DONE_INTR:
            /* reset MASK_EN[0] bit in DMA Control Port to disable DMA write done interrupt. */
            tempIntrMask = UPD_DMA_WRITE_DONE_INTR;
            break;
#endif

        case MSG_RDY_IN_BME_DPRAM_INTR :
            /* reset MASK_EN[1] bit in DMA Control Port to disable Message ready in DPRAM interrupt.*/
            tempIntrMask = UPD_MSG_RDY_IN_BME_DPRAM_INTR;
            break;

        case ALL_INTERRUPTS :
#ifndef CPE_40
            /* reset MASK_EN[0] & MASK_EN[1] bits in DMA Control Port to disable both the interrupts */
            tempIntrMask = UPD_DMA_WRITE_DONE_INTR | UPD_MSG_RDY_IN_BME_DPRAM_INTR;
#else
            tempIntrMask = UPD_MSG_RDY_IN_BME_DPRAM_INTR;
#endif
            break;

        default :
            IK_PRINTF ("\nwrong interrupt to disable.");
            return;
    }

    /* write the value to DMA Control Port */
    writeControlPort(baseAddr, (DMA_CTRL_PORT), tempIntrMask);

#ifdef _DEBUG_
/*  IK_PRINTF ("\nInterrupt value disabled is 0x%2x", tempIntrMask);*/
#endif /* _DEBUG_ */

    return;
}

/********************************************************************************\
    Name       : bmeRdStatus
    Purpose    : To read BME FIFO/interrupt status.

    Parameters :
    no     Name        Type        Description
    --     ----        ----        -----------
    1. bmeStruct    tBmeStruct* BME structure address

    Return     :
    Type        Description
    ----        -----------
    BYTE        FIFO/interrupt status

\********************************************************************************/

BYTE bmeRdStatus(tBmeStruct *bmeStruct)
{
    BYTE *baseAddr;
    BYTE   bFifoStatus;

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

    /* Read DMA Status Port to get the BME FIFO/interrupt status */
#ifndef _BME_TEST_CODE_
#ifndef ALASKA
    readControlPort (baseAddr, (DMA_STATUS_PORT), bFifoStatus);
#else
    readControlPort (baseAddr, (DMA_STATUS_PORT), &bFifoStatus);
#endif
#else /* _BME_TEST_CODE_ */
    readControlPort (baseAddr, (DMA_STATUS_PORT), &bFifoStatus);
#endif /* _BME_TEST_CODE_ */
#ifdef _PARALLEL_IO_INTERFACE_
    bFifoStatus = bRdDataVal;
#endif /* _PARALLEL_IO_INTERFACE_ */

    /* status[0] - DW_H bit indicates DMA write done status
       ( Either host can write more to the FIFO as HIC FIFO empty.
       Or host can read more from the FIFO as the FIFO is full) */

    /* status[1] - DW_T bit indicates DMA  write done status
     (message is in DPRAM. Tensilica can read the message from DPRAM) */

    /* status[2] - MR_H bit indicates message is ready in DPRAM
     (Host can initiate transfer from DPRAM to output FIFO) */

    /* status[3...7] - reserved */
    /* Note :
     1. If DMA write done interrupt is enabled, an interrupt will be
        generated to host if DW_H bit is set.
     2. If Message ready in DPRAM interrupt is enabled, an interrupt
        will be generated to host if MR_H bit is set. */

#ifdef CPE_40
    if (bFifoStatus & MSG_RDY_IN_BME_DPRAM)
    {
        bmeStruct->hicStatus |=  MSG_RDY_IN_BME_DPRAM; }
    else {
        bmeStruct->hicStatus &=  ~MSG_RDY_IN_BME_DPRAM;
    }
    return (bmeStruct->hicStatus);
#endif
    return (bFifoStatus);
}

/********************************************************************************\
    Name       : bmeClrStatus
    Purpose    : To clear BME FIFO/interrupt status.
    Parameters :
    no     Name        Type        Description
    --     ----        ----        -----------
    1. bmeStruct    tBmeStruct* BME structure address
    2. statusMask   BYTE        status mask

    Return     : void
\********************************************************************************/

void bmeClrStatus(tBmeStruct *bmeStruct, BYTE statusMask)
{
    BYTE *baseAddr;
    BYTE   tempVal = 0;

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

    /* set ACK[0] bit to clear DMA write done (DW_H bit) status.
       This indicates HIC FIFO is not empty. HIC FIFO has some data
       or message written by Host. BME has to read the data or message
       from the FIFO. */
    if (statusMask & CLR_DW_H_DMA_WRITE_DONE) {
#ifdef CPE_40
        bmeStruct->hicStatus &= ~DW_H_DMA_WRITE_DONE;
#else
        tempVal |= CLR_DW_H_DMA_WRITE_DONE;
#endif
    }

    /* set ACK[1] bit to clear Message ready in DPRAM (MR_H bit) status.
       This indicates BME can prepare & put more messages in DPRAM for
       the host to read. */
    if (statusMask & CLR_MSG_RDY_IN_BME_DPRAM)
        tempVal |= CLR_MSG_RDY_IN_BME_DPRAM;

    /* debug_printf ("\nstatus value is %d", tempVal);*/

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

    return;
}

/********************************************************************************\
    Name       : bmeWrMemory
    Purpose    : To write data to BME memory.
    Parameters :
    no     Name         Type           Description
    --     ----         ----           -----------
    1. bmeStruct    tBmeStruct* BME structure address
    2. destAddr     UINT32      Destination Address where the data has to
                                    be written
    3. data         BYTE*       Data
    4. numData      int         Number of data bytes (1 - 256 bytes)

    Return     :
    Type        Description
    ----        -----------
    int     1. if successful, HWAPI_WRITE_SUCCESS
            2. if wrong numData, HWAPI_INVALID_LENGTH

\********************************************************************************/

HWAPI_RET_VAL bmeWrMemory(tBmeStruct *bmeStruct, UINT32 destAddr, BYTE *data, int numData)
{
    BYTE *baseAddr;
//    BYTE   tempVal;


#ifdef CPE_40
    UINT32 pioDestAddr;
#else
    int index;
    UINT32 dataVal = 0;
#endif

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

#ifdef CPE_40

    pioDestAddr = destAddr;
    bmePioBulkWrite (bmeStruct, pioDestAddr, data, numData);

    bmeStruct->hicStatus |= DW_H_DMA_WRITE_DONE;

#else
    /* read the DMA status bits */
    tempVal = bmeRdStatus (bmeStruct);

    /*EventLog("b%dp0 bmeWrMemory: status 0x%x *data 0x%x, numData %d"
                ,bmeStruct->BmeNum,tempVal,*data,numData);*/

    /* check the data length (1 - 256) */
    if ((numData < 1) || (numData > 0x100))
    {
        IK_PRINTF ("b%dp0 ...bmeWrMemory Rv HWAPI_INVALID_LENGTH: invalid data len %d",bmeStruct->BmeNum,numData);

        return (HWAPI_INVALID_LENGTH);
    }

    /* check the status[0] (DW_H) bit of DMA Status Port to be zero.
       This indicates HIC FIFO is empty to take data from host. */
    if (tempVal & DW_H_DMA_WRITE_DONE)
    {
        IK_PRINTF("b%dp0 ...bmeWrMemory DW_H bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);

        return (HWAPI_FAILURE_FIFO_NOT_AVAILABLE);
    }

    /* program DMA_CCR15 - Channel Control Register */
if (bmeStruct->FifoFlag==0)
    {dataVal = 0x00001000; /* memory to memory transfer */

    }
if  (bmeStruct->FifoFlag==1)
    dataVal = 0x00001200; /* FIFO to memory transfer */

    bmePioWrite (bmeStruct, DMA_CCR(0, DMA_CH_15), (BYTE *)&dataVal);


    /* set the DMA Length Port with the number of bytes to write. 0 based length */
    writeControlPort (baseAddr, (DMA_LENGTH_PORT), (numData-1));
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_LEN_WR_CMD);

    convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&destAddr);

    //EventLog ("b%dp0 ...bmeWrMemory destAddr 0x%08lx",bmeStruct->BmeNum,destAddr);


    /* set the DMA destination addr Port with the destination address. */
    for (index = 0; index < MAX_ADDR_LINES; index++)
    {
        tempVal = (BYTE)((destAddr & (0xff000000 >> (index * 8))) >> ((MAX_ADDR_LINES - (index + 1)) * 8));
        writeControlPort (baseAddr, (DMA_DEST_ADDR_PORT), tempVal);
    }
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_DST_ADDR_WR_CMD);

    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_SRC_ADDR_WR_CMD);

    /* set the DMA Data Port with the data to be written. */
    for (index = 0; index < numData; index++)
    {
        tempVal = *(data+index);
        writeControlPort (baseAddr, (DMA_DATA_PORT), tempVal);
    }

    /*delay();*/

    /* set the Command Port to Start DMA Write memory or Start
       DMA write FIFO command. */
    writeControlPort (baseAddr, (COMMAND_PORT), DMA_WRITE_MEMORY_CMD);

    /*bmePioRead (&Bme[1], DMA_CCR(0, DMA_CH_15), (BYTE *)&data);
    IK_PRINTF ("\n--> DMA_CCR 0x%08lx", data);*/



    //EventLog("b%dp0 ...bmeWrMemory Rv HWAPI_WRITE_SUCCESS",bmeStruct->BmeNum);
#endif

    return (HWAPI_WRITE_SUCCESS);
}

/********************************************************************************\
    Name       : bmeTrMemory
    Purpose    : To initiate data transfer from BME memory to output FIFO.

    Parameters :
    no     Name         Type           Description
    --     ----         ----           -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. srcAddr      UINT32          Source Address from where the data has to be
                                        transferred from
    3. numData      int             Number of data bytes (1 - 256 bytes)

    Return     :
    Type        Description
    ----        -----------
    int     1. if successful, HWAPI_TRANSFER_SUCCESS
            2. if error, HWAPI_FAILURE_FIFO_NOT_AVAILABLE
            3. if wrong numData, HWAPI_INVALID_LENGTH

\********************************************************************************/

HWAPI_RET_VAL bmeTrMemory(tBmeStruct *bmeStruct, UINT32 srcAddr, int numData)
{
    BYTE *baseAddr;
#ifndef CPE_40
    BYTE tempVal;
    BYTE   index;
    UINT32 data = 0;
#else
	numData++;
#endif

    /* get the base address of the BME chip */
    baseAddr = (BYTE *)bmeStruct->BMEbaseAddr;
#ifdef CPE_40
    bmeStruct->srcAddr = srcAddr;
    bmeStruct->hicStatus |= DW_H_DMA_WRITE_DONE;
#else

    /* program DMA_CCR15 - Channel Control Register */
if (bmeStruct->FifoFlag==0)
    {
    data = 0x00001000; /* memory to memory transfer */

    }
if  (bmeStruct->FifoFlag==1)
    data = 0x00001400; /* FIFO to memory transfer */

    bmePioWrite (bmeStruct, DMA_CCR(0, DMA_CH_15), (BYTE *)&data);

    //EventLog("b%dp0 bmeTrMemory: status 0x%x srcAddr 0x%x, numData %d",bmeStruct->BmeNum,tempVal,srcAddr,numData);

    /* check the data length (1 - 256) */
    if ((numData < 1) || (numData > 0x100))
    {
        //EventLog ("b%dp0 ...bmeTrMemory Rv HWAPI_INVALID_LENGTH: wrong data length, numData %d",bmeStruct->BmeNum,numData);

        return (HWAPI_INVALID_LENGTH);
    }

    tempVal = bmeRdStatus (bmeStruct);
/* check the status[0] (DW_H) bit of DMA Status Port to be zero. This indicates
       whether the FIFO is empty to take the data from BME memory. */

    if (tempVal & DW_H_DMA_WRITE_DONE)
    {
        IK_PRINTF("b%dp0 ...bmeTrMemory DW_H bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);

        /*EventLog("b%dp0 ...bmeTrMemory Rv HWAPI_FAILURE_FIFO_NOT_AVAILABLE: FIFO not empty to take data from bme memory "
            ,bmeStruct->BmeNum);*/

        return (HWAPI_FAILURE_FIFO_NOT_AVAILABLE);
    }

    /* set the DMA Length Port with the number of bytes to transfer. */
    writeControlPort (baseAddr, (DMA_LENGTH_PORT), (numData-1));
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_LEN_RD_CMD);

    convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&srcAddr);

    /* set the DMA source addr Port with the source address to transfer
       data from. */
    for (index = 0; index < MAX_ADDR_LINES; index++)
    {
        tempVal = (BYTE)((srcAddr & (0xff000000 >> (index * 8))) >> ((MAX_ADDR_LINES - (index + 1)) * 8));
        writeControlPort (baseAddr, (DMA_SRC_ADDR_PORT), tempVal);
    }
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_SRC_ADDR_RD_CMD);

    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_DST_ADDR_RD_CMD);

    /* set the Command Port to Start DMA Read memory or Start DMA Read FIFO
    command.The read data will be placed in output FIFO. */
    writeControlPort (baseAddr, (COMMAND_PORT), DMA_READ_MEMORY_CMD);

#endif
    return (HWAPI_TRANSFER_SUCCESS);

} /* bmeTrMemory */

/********************************************************************************\
    Name       : bmeRdMemory
    Purpose    : To read data from BME FIFO.

    Parameters :
    no     Name         Type           Description
    --     ----         ----           -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. data         BYTE*           Data buffer

    Return     :
    Type        Description
    ----        -----------
    int     1. if success, HWAPI_READ_SUCCESS
            2. if error, HWAPI_FAILURE_DATA_NOT_PRESENT, HWAPI_INVALID_LENGTH

\********************************************************************************/

HWAPI_RET_VAL bmeRdMemory(tBmeStruct *bmeStruct, BYTE *data)
{
    BYTE *baseAddr;
    int    dataLen;
#ifdef CPE_40
    UINT32 pioSrcAddr;
#else
    BYTE   tempVal;
    int    index;
#endif

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

    /* get the data length */
    dataLen = bmeStruct->dataLen;

#ifdef CPE_40

    if (bmeStruct->srcAddr == DPRAM_BASE_ADDR)
        pioSrcAddr = DPRAM_TX_BASE_ADDR;
    else
        pioSrcAddr = bmeStruct->srcAddr;

    bmePioBulkRead (bmeStruct, pioSrcAddr, data, dataLen);

#else
    tempVal = bmeRdStatus (bmeStruct);

    /*EventLog("b%dp0 bmeRdMemory status 0x%x, *data %x, dataLen 0x%x",bmeStruct->BmeNum
                ,*data,tempVal,dataLen);*/

    /* check for data length (1 - 256) bytes */
    if ((dataLen < 1) || (dataLen > 0x100))
    {
        /*EventLog("b%dp0 ...bmeRdMemory Rv HWAPI_INVALID_LENGTH: wrong data length dataLen 0x%x"
            ,bmeStruct->BmeNum,dataLen);*/
        IK_PRINTF("bmeRdMemory: HWAPI_INVALID_LENGTH\n");
        return (HWAPI_INVALID_LENGTH);
    }

    /* This routine will follow bmeTrMemory() command.
   check the status[0] (DW_H) bit of DMA Status Port to be one.
   This indicates data has been transferred from BME memory to FIFO. */

    if (!(tempVal & DW_H_DMA_WRITE_DONE))
    {
        IK_PRINTF("b%dp0 ...bmeRdMemory DW_H bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);
        /*EventLog ("b%dp0 ...bmeRdMemory Rv HWAPI_FAILURE_DATA_NOT_PRESENT: DMA write from bme memory to FIFO not done tempVal=%x"
            ,bmeStruct->BmeNum,tempVal);*/
        IK_PRINTF("bmeRdMemory: HWAPI_FAILURE_DATA_NOT_PRESENT\n");
        return (HWAPI_FAILURE_DATA_NOT_PRESENT);
    }

    /* Read the data from FIFO for the size specified in bmeTrMemory() command
       and put it in dataPtr being passed. */

    for (index = 0; index < dataLen; index++)
    {
#ifndef _BME_TEST_CODE_
#ifndef ALASKA
        readControlPort (baseAddr, (DMA_DATA_PORT), *(data+index));
#else
        readControlPort (baseAddr, (DMA_DATA_PORT), (data+index));
#endif
        /*IK_PRINTF ("\n data %x ",*data);
        if (BmeResetVecCode[index]!=*data) IK_PRINTF ("\nData mismatch index%i,exp %x real %x",
                            index,BmeResetVecCode[index],*data);*/

#else /* _BME_TEST_CODE_ */
        readControlPort (baseAddr, (DMA_DATA_PORT), (data+index));
#endif /* _BME_TEST_CODE_ */
#ifdef _PARALLEL_IO_INTERFACE_
        *(data+index) = bRdDataVal;
 /*
        if (!(index%16))
            IK_PRINTF ("\n");
        IK_PRINTF ("ttttt0x%02x ", bRdDataVal);
*/
#endif /* _PARALLEL_IO_INTERFACE_ */

    }

    /* clear the DW_H bit status by writing to the HOST Ack Port */
    bmeClrStatus (bmeStruct, CLR_DW_H_DMA_WRITE_DONE);

#endif
    //EventLog("b%dp0 ...bmeRdMemory Rv HWAPI_READ_SUCCESS", bmeStruct->BmeNum);



    return (HWAPI_READ_SUCCESS);
}

/********************************************************************************\
    Name       : bmeWrMessage
    Purpose    : To write a message to BME.

    Parameters :
    no     Name         Type           Description
    --     ----         ----           -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. destAddr     UINT32          Destination Address where the message has
                                        to be written
    3. message      BYTE*           Message
    4. msgLen       int             Length of message (up to 256 bytes)

    Return     :
    Type        Description
    ----        -----------
    int     1. if sucess, HWAPI_WRITE_SUCCESS
            2. if invalid msgLen, HWAPI_INVALID_LENGTH
            3. if error, HWAPI_FAILED
\********************************************************************************/

HWAPI_RET_VAL bmeWrMessage(tBmeStruct *bmeStruct, UINT32 destAddr, BYTE *data, int numData)
{
    BYTE *baseAddr;
#ifdef CPE_40
    UINT32 pioDestAddr;
    UINT32 pio_isr_val;
#else
    BYTE   tempVal;
    int index;
    int i = 0;
    UINT32 dataVal = 0;
#endif

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

#ifdef CPE_40
    pioDestAddr = destAddr;
    bmePioBulkWrite (bmeStruct, pioDestAddr, data, numData);

    bmeStruct->hicStatus |= DW_H_DMA_WRITE_DONE;

    bmePioRead  (bmeStruct, PIO_ISR(0), (BYTE *)&pio_isr_val);
#ifdef CPE_50
    pio_isr_val |= 1;
#else
    pio_isr_val |= (1 << 8);
#endif
    bmePioWrite (bmeStruct, PIO_ISR(0), (BYTE *)&pio_isr_val);
#else
    /* check the data length (1 - 256) */
    if ((numData < 1) || (numData > 0x100))
    {
        //EventLog("b%dp0 ...bmeWrMemory Rv HWAPI_INVALID_LENGTH: invalid data len %d",bmeStruct->BmeNum,numData);

        return (HWAPI_INVALID_LENGTH);
    }

    /* read the DMA status bits */

    tempVal = bmeRdStatus (bmeStruct);

    /*EventLog("b%dp0 bmeWrMessage: status 0x%x *data 0x%x, numData %d"
                ,bmeStruct->BmeNum,tempVal,*data,numData);*/

    /* check the status[0] (DW_H) bit of DMA Status Port to be zero.
       This indicates HIC FIFO is empty to take data from host. */
    if (tempVal & DW_H_DMA_WRITE_DONE)
    {
        /*EventLog("b%dp0 ...bmeWrMessage Rv HWAPI_FAILURE_FIFO_NOT_AVAILABLE: HIC FIFO is not empty to take data from host"
                ,bmeStruct->BmeNum);*/
        IK_PRINTF("b%dp0 ...bmeWrMessage DW_H bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);
        return (HWAPI_FAILURE_FIFO_NOT_AVAILABLE);
    }

    while (  tempVal & DW_T_DMA_WRITE_DONE) {

        tempVal = bmeRdStatus (bmeStruct);
        iposTaskDelay(10);
        //IK_PRINTF("HWAPI_FAILURE_FIFO_NOT_AVAILABLE\n");

        i++;
        if(i>=DWT_CLR_TIMEOUT)
        {
            IK_PRINTF("b%dp0 ...bmeWrMessage DW_T bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);
            return (HWAPI_FAILURE_FIFO_NOT_AVAILABLE);
        }
    }

    /* program DMA_CCR15 - Channel Control Register */
if (bmeStruct->FifoFlag==0)
    {dataVal = 0x00001000; /* memory to memory transfer */

    }
if  (bmeStruct->FifoFlag==1)
    dataVal = 0x00001200; /* FIFO to memory transfer */

    bmePioWrite (bmeStruct, DMA_CCR(0, DMA_CH_15), (BYTE *)&dataVal);


    /* set the DMA Length Port with the number of bytes to write. 0 based length */
    writeControlPort (baseAddr, (DMA_LENGTH_PORT), (numData-1));
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_LEN_WR_CMD);

    convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&destAddr);

    //EventLog ("b%dp0 ...bmeWrMessage destAddr 0x%08lx",bmeStruct->BmeNum,destAddr);



    /* set the DMA destination addr Port with the destination address. */
    for (index = 0; index < MAX_ADDR_LINES; index++)
    {
        tempVal = (BYTE)((destAddr & (0xff000000 >> (index * 8))) >> ((MAX_ADDR_LINES - (index + 1)) * 8));
        writeControlPort (baseAddr, (DMA_DEST_ADDR_PORT), tempVal);
    }
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_DST_ADDR_WR_CMD);

    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_SRC_ADDR_WR_CMD);

    /* set the DMA Data Port with the data to be written. */
    for (index = 0; index < numData; index++)
    {
        tempVal = *(data+index);
        //writeControlPort (baseAddr, (DMA_DATA_PORT), tempVal);
        writeControlPort (baseAddr, (DMA_DATA_PORT), *(data+index));

    }

    /*delay();*/

    /* set the Command Port to Start DMA Write memory or Start
       DMA write FIFO command. */
    writeControlPort (baseAddr, (COMMAND_PORT), DMA_WRITE_MEMORY_CMD);

    /*bmePioRead (&Bme[1], DMA_CCR(0, DMA_CH_15), (BYTE *)&data);
    IK_PRINTF ("\n--> DMA_CCR 0x%08lx", data);*/


    //EventLog("b%dp0 ...bmeWrMessage Rv HWAPI_WRITE_SUCCESS",bmeStruct->BmeNum);

#endif
    return (HWAPI_WRITE_SUCCESS);
}

// Original bmeWrMessage

#if 0
HWAPI_RET_VAL bmeWrMessage(tBmeStruct *bmeStruct, BYTE *message, int msgLen)
{
    BYTE *baseAddr;
    BYTE   tempVal=0;
    UINT32 destAddr=0;
    int index=0;
    UINT32 dataVal=0;

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

    /* read the DMA Status Port */
    tempVal = bmeRdStatus (bmeStruct);

    /*EventLog("b%dp0 bmeWrMessage src 0x%x, status 0x%x, msgLen 0x%x dpramBaseRxAddr 0x%x",bmeStruct->BmeNum
                ,*message,tempVal,msgLen,bmeStruct->dpramBaseRxAddr);*/

    /* check the data length (1 - 256) */
    if ((msgLen < 1) || (msgLen > 0x100))
    {
        /*EventLog("b%dp0...bmeWrMessage Rv: HWAPI_INVALID_LENGTH, wrong data length %d"
            ,bmeStruct->BmeNum,msgLen);*/

        return (HWAPI_INVALID_LENGTH);
    }

#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    /* check the DMA Status bits only for the first time */
    if (firstWrite == TRUE)
    {
#endif /* MSG_BUFFERING_IN_DPRAM */

    /* check the status[0] (DW_H) bit of DMA Status Port to be zero.
    This indicates HIC FIFO is empty to take data from host.*/
    if (tempVal & DW_H_DMA_WRITE_DONE)
        {
        /*EventLog("b%dp0 ...bmeWrMessage Rv: HWAPI_FAILURE_FIFO_NOT_AVAILABLE. DW_H is 1. FIFO not empty to take data from host. MR_H %x ",
            bmeStruct->BmeNum,(tempVal & DW_H_DMA_WRITE_DONE));*/
        IK_PRINTF("b%dp0 ...bmeWrMessage DW_H bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);
        return (HWAPI_FAILURE_FIFO_NOT_AVAILABLE);
        }

    /* check the status[1] (DW_T) bit of DMA Status Port to be zero.
       This indicates DPRAM is ready to take the data from the host. */
    if (tempVal & DW_T_DMA_WRITE_DONE)
        {
        /*EventLog("b%dp0 ...bmeWrMessage Rv: HWAPI_FAILURE_FIFO_NOT_AVAILABLE. DW_T is 1. FIFO not empty to take data from host. BMEBaseAddr %x, MR_H %x ",
            bmeStruct->BmeNum);*/
        IK_PRINTF("b%dp0 ...bmeWrMessage DW_T bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);
        return (HWAPI_FAILURE_FIFO_NOT_AVAILABLE);
        }

    /* program DMA_CCR15 - Channel Control Register */
    if (bmeStruct->FifoFlag==0)
        {dataVal = 0x00001000; /* memory to memory transfer */}
    if  (bmeStruct->FifoFlag==1)
        dataVal = 0x00001200; /* FIFO to memory transfer */

    bmePioWrite (bmeStruct, DMA_CCR(0, DMA_CH_15), (BYTE *)&dataVal);


#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    }
    if (writeBufCnt < MAX_MSG_BUFFERS_IN_DPRAM)
    {
#endif /* MSG_BUFFERING_IN_DPRAM */

    /* set the DMA Length Port with the number of bytes to write. */
    writeControlPort (baseAddr, (DMA_LENGTH_PORT), (msgLen-1));
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_LEN_WR_CMD);

#ifndef _BME_TEST_CODE_
#ifndef MSG_BUFFERING_IN_DPRAM
    destAddr = bmeStruct->dpramBaseRxAddr;
#else /* MSG_BUFFERING_IN_DPRAM */
    destAddr = bmeStruct->dpramBaseRxAddr + (writeBufCnt * MAX_FIFO_LENGTH);
#endif /* MSG_BUFFERING_IN_DPRAM */
#else /* _BME_TEST_CODE_ */
    destAddr = (UINT32)BmeRxDpram;
#endif /* _BME_TEST_CODE_ */

    convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&destAddr);

    //EventLog ("b%dp0 ...bmeWrMessage destAddr 0x%08lx",bmeStruct->BmeNum,destAddr);

    /* set the DMA destination addr Port with the destination address. */
    for (index = 0; index < MAX_ADDR_LINES; index++)
    {
        tempVal = (BYTE)((destAddr & (0xff000000 >> (index * 8))) >> ((MAX_ADDR_LINES - (index + 1)) * 8));
        /*sim_printf ("\ntempVal is 0x%x", tempVal);*/
        writeControlPort (baseAddr, (DMA_DEST_ADDR_PORT), tempVal);
    }
    writeControlPort (baseAddr,( COMMAND_PORT), UPD_DMA_DST_ADDR_WR_CMD);
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_SRC_ADDR_WR_CMD);

    /* set the DMA Data Port with the message to be written. */
    for (index = 0; index < msgLen; index++)
    {
        tempVal = *(message+index);
        writeControlPort (baseAddr, (DMA_DATA_PORT|((bmeStruct->BmeNum-1))<<4), tempVal);
    }

    /* set the Command Port to Start DMA Write memory command. */
    writeControlPort (baseAddr, (COMMAND_PORT), DMA_WRITE_MEMORY_CMD);



#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    writeBufCnt++;
    if (firstWrite == TRUE)
        firstWrite = FALSE;
#endif /* MSG_BUFFERING_IN_DPRAM */

        //EventLog("b%dp0 ...bmeWrMessage Rv: HWAPI_WRITE_SUCCESS", bmeStruct->BmeNum);

    return (HWAPI_WRITE_SUCCESS);

#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    } /* end of "if (bufCnt < MAX_MSG_BUFFERS_IN_DPRAM)" */
    else
    {
        //EventLog("b%dp0 ...bmeWrMessage Rv: HWAPI_FAILED: Write Buffer Count reached max number!"
            , bmeStruct->BmeNum);

        return (HWAPI_FAILED);
    }
#endif /* MSG_BUFFERING_IN_DPRAM */

} /* bmeWrMessage */
#endif

/********************************************************************************\
    Name       : bmeTrMessage
    Purpose    : To initiate message transfer from BME message queue / DPRAM
                    to output FIFO

    Parameters :
    no     Name         Type           Description
    --     ----         ----           -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. srcAddr      UINT32          Source Address from where the message has
                                        to be transferred from

    Return     :
    Type        Description
    ----        -----------
    int     1. if success, HWAPI_TRANSFER_SUCCESS
            2. if error, HWAPI_FAILED
\********************************************************************************/

#ifndef CPE_40

HWAPI_RET_VAL bmeTrMessage(tBmeStruct *bmeStruct)
{
    BYTE *baseAddr;
    BYTE   tempVal, index;
    UINT32 srcAddr;
    UINT32 dataVal=0;

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

    tempVal = bmeRdStatus (bmeStruct);

    //EventLog ("b%ip0 bmeTrMessage: status 0x%x",bmeStruct->BmeNum,tempVal);

#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    if (firstRead == TRUE)
    {
#endif /* MSG_BUFFERING_IN_DPRAM */
    /* check the status[0] (DW_H) bit of DMA Status Port to be zero. This indicates
       whether the FIFO is empty to take the data from BME memory. */
    if (tempVal & DW_H_DMA_WRITE_DONE)
    {
        IK_PRINTF("b%dp0 ...bmeTrMessage DW_H bit not cleared. Status %i",bmeStruct->BmeNum,tempVal);
        /*EventLog("b%ip0 ...bmeTrMessage Rv HWAPI_FAILED: FIFO not empty to take data from bme memory. BMEBaseAddr %x DW_H %x ",
                bmeStruct->BmeNum,(tempVal & DW_H_DMA_WRITE_DONE));*/
        return (HWAPI_FAILED);
    }

    /* check the status[2] (MR_H) bit (message ready in DPRAM) of  DMA Status
    Port to be one. This indicates message is present in DPRAM to be
    transferred. */
    if (!(tempVal & MSG_RDY_IN_BME_DPRAM))
    {
        IK_PRINTF("b%dp0 ...bmeTrMessage MR_H bit not set. Status %i",bmeStruct->BmeNum,tempVal);
        /*EventLog("b%ip0 ...bmeTrMessage Rv HWAPI_FAILED: Msg is not ready in DPRAM. BMEBaseAddr %x, MR_H %x ",
                bmeStruct->BmeNum,(tempVal & MSG_RDY_IN_BME_DPRAM));*/
        return (HWAPI_FAILED);
    }

#ifdef CPE_40
    bmeStruct->hicStatus |= DW_H_DMA_WRITE_DONE;
    return (HWAPI_TRANSFER_SUCCESS);
#else

    /* program DMA_CCR15 - Channel Control Register */
    if (bmeStruct->FifoFlag==0)
        {dataVal = 0x00001000; /* memory to memory transfer */}
    if  (bmeStruct->FifoFlag==1)
        dataVal = 0x00001200; /* FIFO to memory transfer */

    bmePioWrite (bmeStruct, DMA_CCR(0, DMA_CH_15), (BYTE *)&dataVal);
#endif

#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    }
    if (readBufCnt < MAX_MSG_BUFFERS_IN_DPRAM)
    {
#endif /* MSG_BUFFERING_IN_DPRAM */

    /* set the DMA Length Port with the number of bytes to transfer - 255. */
    writeControlPort (baseAddr, (DMA_LENGTH_PORT), 0xff);
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_LEN_RD_CMD);

#ifndef _BME_TEST_CODE_
#ifndef MSG_BUFFERING_IN_DPRAM
    srcAddr = bmeStruct->dpramBaseTxAddr;
#else /* MSG_BUFFERING_IN_DPRAM */
    srcAddr = bmeStruct->dpramBaseTxAddr + (readBufCnt * MAX_FIFO_LENGTH);
#endif /* MSG_BUFFERING_IN_DPRAM */
#else /* _BME_TEST_CODE_ */
    srcAddr = (ULONG)BmeTxDpram;
/*  IK_PRINTF ("\nSrc addr %lx, BmeTxDpram addr %lx", srcAddr, BmeTxDpram);*/
#endif /* _BME_TEST_CODE_ */

    convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&srcAddr);
    //EventLog ("b%dp0 ...bmeTrMessage srcAddr 0x%x",bmeStruct->BmeNum,srcAddr);

    /* set the DMA source addr Port with the source address to transfer message
       from. */
    for (index = 0; index < MAX_ADDR_LINES; index++)
    {
        tempVal = (BYTE)((srcAddr & (0xff000000 >> (index * 8))) >> ((MAX_ADDR_LINES - (index + 1)) * 8));
        writeControlPort (baseAddr, (DMA_SRC_ADDR_PORT), tempVal);
    }
    writeControlPort (baseAddr, (COMMAND_PORT), UPD_DMA_SRC_ADDR_RD_CMD);

    /* set the Command Port to Start DMA Read memory command.The read message
       will be placed in output FIFO. */
    writeControlPort (baseAddr, (COMMAND_PORT), DMA_READ_MEMORY_CMD);

    //EventLog("b%dp0 ...bmeTrMessage Rv HWAPI_TRANSFER_SUCCESS", bmeStruct->BmeNum);

    return (HWAPI_TRANSFER_SUCCESS);

#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    }
    else
    {
        /*EventLog("b%ip0 ...bmeTrMessage Rv HWAPI_FAILED: Read Buffer Count reached max number! ",
                bmeStruct->BmeNum);*/
        retVal = HWAPI_FAILED;
    }
#endif /* MSG_BUFFERING_IN_DPRAM */

//#endif
}
#endif //#ifndef CPE_40

/********************************************************************************\
    Name       : bmeRdMessage
    Purpose    : To read message from BME FIFO.

    Parameters :
    no     Name         Type           Description
    --     ----         ----           -----------
    1. bmeStruct    tBmeStruct*     BME structure address
    2. message      BYTE*           Message buffer

    Return     :
    Type        Description
    ----        -----------
    int     1. if success, HWAPI_READ_SUCCESS
            2. if error, HWAPI_FAILED
\********************************************************************************/

HWAPI_RET_VAL bmeRdMessage(tBmeStruct *bmeStruct, BYTE *message)
{
    BYTE *baseAddr, tempVal;

#ifdef CPE_40
    UINT32 srcAddr;
    UINT32 pioSrcAddr;
#else
    int index;
#endif

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

    /* This routine will follow bmeTrMessage() command.
    check the status[0] (DW_H) bit of DMA Status Port to be one.
    This indicates whether message has been transferred from BME memory /
    DPRAM to FIFO. */

    tempVal = bmeRdStatus (bmeStruct);

    //EventLog ("b%dp0 bmeRdMessage status: 0x%x, *message 0x%x",bmeStruct->BmeNum,tempVal,*message);
#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    if (firstRead == TRUE)
    {
#endif /* MSG_BUFFERING_IN_DPRAM */
#ifndef CPE_50 // JW!!
    if (!(tempVal & DW_H_DMA_WRITE_DONE))
    {
        IK_PRINTF("b%dp0 ...bmeRdMessage DW_H bit not set. Status %i",bmeStruct->BmeNum,tempVal);
        /*EventLog ("b%dp0 ...bmeRdMessage Rv HWAPI_FAILED: DMA write from DPRAM to FIFO not done"
                    ,bmeStruct->BmeNum);*/
        return (HWAPI_FAILED);
    }
#endif
#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    }
    if (readBufCnt <  MAX_MSG_BUFFERS_IN_DPRAM)
    {
#endif /* MSG_BUFFERING_IN_DPRAM */

#ifdef CPE_40

#ifndef _BME_TEST_CODE_
    pioSrcAddr = bmeStruct->dpramBaseTxAddr;
#else /* _BME_TEST_CODE_ */
    pioSrcAddr = (UINT32)BmeTxDpram;
/*  IK_PRINTF ("\nSrc addr %lx, BmeTxDpram addr %lx", srcAddr, BmeTxDpram);*/
#endif /* _BME_TEST_CODE_ */

    bmePioBulkRead (bmeStruct, pioSrcAddr, message, 0x100);

#else /* CPE_40 */
    /* Read the message from FIFO for the size 256 and put it in messagePtr
       being passed. */
    for (index = 0; index < 0x100; index++)
    {
#ifndef _BME_TEST_CODE_
#ifndef ALASKA
        readControlPort (baseAddr, (DMA_DATA_PORT), *(message+index));
#else
        readControlPort (baseAddr, (DMA_DATA_PORT), (message+index));
#endif
#else /* _BME_TEST_CODE_ */
        readControlPort (baseAddr, (DMA_DATA_PORT), (message+index));
#endif /* _BME_TEST_CODE_ */
#ifdef _PARALLEL_IO_INTERFACE_
        *(message+index) = bRdDataVal;
#endif /* _PARALLEL_IO_INTERFACE_ */

    }

#endif /* CPE_40 */

#ifndef MSG_BUFFERING_IN_DPRAM
    /* send host acknowledge to clear the dma write done DW_H as well as
    message ready status bits in dma status port */
    bmeClrStatus (bmeStruct, CLR_DW_H_DMA_WRITE_DONE | CLR_MSG_RDY_IN_BME_DPRAM);
#else /* MSG_BUFFERING_IN_DPRAM */
    readBufCnt++;
    if (firstRead == TRUE)
        firstRead = FALSE;

    if (readBufCnt >= MAX_MSG_BUFFERS_IN_DPRAM)
    {
        /* send host acknowledge to clear the dma write done DW_H as well as
        message ready status bits in dma status port */
        bmeClrStatus (bmeStruct, CLR_DW_H_DMA_WRITE_DONE | CLR_MSG_RDY_IN_BME_DPRAM);
        firstRead = TRUE;
        readBufCnt = 0;
    }
#endif /* MSG_BUFFERING_IN_DPRAM */

    //EventLog ("b%dp0 ...bmeRdMessage Rv HWAPI_READ_SUCCESS",bmeStruct->BmeNum);



    return (HWAPI_READ_SUCCESS);

#ifndef MSG_BUFFERING_IN_DPRAM
#else /* MSG_BUFFERING_IN_DPRAM */
    }
    else
    {
        /*EventLog ("b%dp0 ...bmeRdMessage Rv HWAPI_FAILED: Read Buffer Count reached max number!"
                    ,bmeStruct->BmeNum);*/

        retVal = HWAPI_FAILED;
    }
#endif /* MSG_BUFFERING_IN_DPRAM */

}

/********************************************************************************\
    Name       : bmePioRead
    Purpose    : To read data from BME through PIO interface.

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address
    2. srcAddr        UINT32        source address from where to read
    3. dataPtr        BYTE *        pointer to store read data

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       HWAPI_PIO_READ_SUCCESS
\********************************************************************************/
HWAPI_RET_VAL bmePioRead (tBmeStruct *bmeStruct, UINT32 srcAddr, BYTE *dataPtr)
{
    BYTE *baseAddr;
    BYTE tempVal, indexx;
#ifdef SW_HIC_DTACK
    volatile int count;
#endif

    //IK_PRINTF ("\nstart");
    /* get the base address of the BME chip */
    baseAddr = (BYTE *)bmeStruct->BMEbaseAddr;
    //printf("base addr:%08x\n",baseAddr);

    /*EventLog ("b%dp0 bmePioRead: SrcAddr: 0x%x, *dataPtr 0x%x",bmeStruct->BmeNum,srcAddr,*dataPtr);
     */
    //convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&srcAddr);

    /* set the PIO addr Port with the source address to transfer data from. */
    //IK_PRINTF ("\nhello");
    for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
    {//IK_PRINTF ("\nhello2");
        tempVal = (BYTE)((srcAddr & (0xff000000 >> (indexx * 8))) >> ((MAX_ADDR_LINES - (indexx + 1)) * 8));
    //IK_PRINTF ("\nhello3 bmenum %x",bmeStruct->BmeNum);
        writeControlPort (baseAddr, (PIO_ADDR_PORT), tempVal);
#ifdef SW_HIC_DTACK
        for (count = 0 ; count < 0; count ++);
#endif
		VERY_SHORT_DELAY(100);
    }

    /* set the Command Port to PIO read register command.
    The read data will be placed in PIO data port. */
    writeControlPort (baseAddr, (COMMAND_PORT), PIO_READ_REG_CMD);
#ifdef SW_HIC_DTACK
    for (count = 0 ; count < 0; count ++);

    /* Considering with no delay its about 800ns, wrt Ikanos reference board
        so  for 2us of delay a count of 1 is given, after measuring on the osc */
    for (count = 0 ; count < 1; count ++);
#endif
		VERY_SHORT_DELAY(100);
    /* Read the data from PIO data port and put it in dataPtr being passed. */
    for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
    {
#ifndef _BME_TEST_CODE_
#ifndef ALASKA
        readControlPort (baseAddr, (PIO_DATA_PORT), *(dataPtr+indexx));
#else
        readControlPort (baseAddr, (PIO_DATA_PORT), (dataPtr+indexx));
#endif
#else /* _BME_TEST_CODE_ */
dd
        readControlPort (baseAddr, (PIO_DATA_PORT), (dataPtr+indexx));
#endif /* _BME_TEST_CODE_ */
#ifdef _PARALLEL_IO_INTERFACE_
dd
        *(dataPtr+indexx) = bRdDataVal;
        bRdDataVal = 0x0;
#endif /* _PARALLEL_IO_INTERFACE_ */
#ifdef SW_HIC_DTACK
        for (count = 0 ; count < 0; count ++);
#endif
		VERY_SHORT_DELAY(100);
    }

   /* EventLog("b%dp0 ...bmePioRead Rv HWAPI_PIO_READ_SUCCESS",bmeStruct->BmeNum);*/

    return (HWAPI_PIO_READ_SUCCESS);
}
extern tBmeStruct BmeStruct[];
void rd(int addr)
{
   static int data;
   bmePioRead(&BmeStruct[1],addr,(BYTE *)&data);
   printf("addr:0x%08x data:0x%08x\n",addr,data);
}

void wr(int addr,int data)
{
   bmePioWrite(&BmeStruct[1],addr,(BYTE *)&data);
   printf("addr:0x%08x data:0x%08x\n",addr,data);
}

/********************************************************************************\
    Name       : bmePioWrite
    Purpose    : To write data to BME through PIO interface.

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address
    2. destAddr       UINT32        destination address of where to write
    3. dataPtr        BYTE *        pointer to data to write

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       HWAPI_PIO_WRITE_SUCCESS
\********************************************************************************/
HWAPI_RET_VAL bmePioWrite (tBmeStruct *bmeStruct, UINT32 destAddr, BYTE *dataPtr)
{
    BYTE *baseAddr;
    BYTE tempVal, indexx;
#ifdef SW_HIC_DTACK
    volatile int count;
#endif

    /* get the base address of the BME chip */
    baseAddr = (BYTE *)bmeStruct->BMEbaseAddr;
    //printf("base addr:%08x\n",baseAddr);

/*  EventLog ("b%dp0 bmePioWrite: destAddr 0x%x, *dataPtr 0x%x",bmeStruct->BmeNum,destAddr,*dataPtr);
  */

/*  convertDataToEndianFormat(sizeof(UINT32), (BYTE *)&destAddr);
*/
    /* set the PIO addr Port with the destination address to transfer data to. */
    for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
    {
        tempVal = (BYTE)((destAddr & (0xff000000 >> (indexx * 8))) >> ((MAX_ADDR_LINES - (indexx + 1)) * 8));
        writeControlPort (baseAddr, (PIO_ADDR_PORT), tempVal);
#ifdef SW_HIC_DTACK
        for (count = 0 ; count < 0; count ++);
#endif
		VERY_SHORT_DELAY(100);
#ifdef _DEBUG_
        /* IK_PRINTF ("\nAddr%x", tempVal); */
#endif /* _DEBUG_ */
    }

    /* write the data from dataPtr to PIO data port. */
    for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
    {

        writeControlPort (baseAddr, (PIO_DATA_PORT), *(dataPtr+indexx));
#ifdef _DEBUG_
        /* IK_PRINTF ("\nData%x", *(dataPtr+indexx)); */
#endif /* _DEBUG_ */
#ifdef SW_HIC_DTACK
        for (count = 0 ; count < 0; count ++);
#endif
		VERY_SHORT_DELAY(100);
    }

    /* set the Command Port to PIO write register command. */
    writeControlPort (baseAddr, (COMMAND_PORT), PIO_WRITE_REG_CMD);


#ifdef SW_HIC_DTACK
    for (count = 0 ; count < 0; count ++);

    /* Considering with no delay its about 800ns, wrt Ikanos reference board
        so  for 2us of delay a count of 1 is given, after measuring on the osc */
    for (count = 0 ; count < 1; count ++);
#endif

    /*EventLog("b%dp0 ...bmePioWrite Rv HWAPI_PIO_WRITE_SUCCESS",
            bmeStruct->BmeNum);
    */
    return (HWAPI_PIO_WRITE_SUCCESS);
}


/********************************************************************************\
    Name       : bmePioBulkRead
    Purpose    : To read data in bulk from BME through PIO interface.

    Parameters :
    no Name     Type        Description
    -- ----     ----        -----------
    1. bmeStruct    tBmeStruct* BME structure address
    2. srcBaseAddr  UINT32      source address from where to read
    3. dataPtr  BYTE *      pointer to data buffer to read into
    4. numBytes UINT32      Number of bytes of data to read

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       HWAPI_PIO_WRITE_SUCCESS
\********************************************************************************/
HWAPI_RET_VAL bmePioBulkRead (tBmeStruct *bmeStruct, UINT32 srcBaseAddr, BYTE *dataPtr, UINT32 numBytes)
{
    BYTE *baseAddr;
    BYTE tempVal;
    UINT32 i, srcAddr, indexx;

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

    srcAddr = srcBaseAddr;

#ifdef HIC_PIO_AUTO_INCR
    /* set the PIO addr Port with the source address to read data from. */
    /* set this once outside the loop if address auto increment is available.  */
    for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
    {
        tempVal = (BYTE)((srcAddr & (0xff000000 >> (indexx * 8))) >> ((MAX_ADDR_LINES - (indexx + 1)) * 8));
        writeControlPort (baseAddr, (PIO_ADDR_PORT), tempVal);
		VERY_SHORT_DELAY(10);
    }
#endif
    /* Loop for PIO read sequences, to read the data 4 bytes at a time */
    for (i = 0; i < numBytes; i += 4, srcAddr += 4)
    {
#ifndef HIC_PIO_AUTO_INCR
        /* set the PIO addr Port with the source address to read data from. */
        /* set this every time with manually incremented adderss if auto increment is not available  */
        for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
        {
            tempVal = (BYTE)((srcAddr & (0xff000000 >> (indexx * 8))) >> ((MAX_ADDR_LINES - (indexx + 1)) * 8));
            writeControlPort (baseAddr, (PIO_ADDR_PORT), tempVal);
			VERY_SHORT_DELAY(10);
        }
#endif
        /* set the Command Port to PIO read register command. */
#ifdef HIC_PIO_AUTO_INCR
        writeControlPort (baseAddr, (COMMAND_PORT), PIO_READ_REG_CMD);
        //writeControlPort (baseAddr, (COMMAND_PORT), PIO_READ_AUTO_INCR_REG_CMD);
#else
        writeControlPort (baseAddr, (COMMAND_PORT), PIO_READ_REG_CMD);
#endif
		VERY_SHORT_DELAY(10);
        /* read the data from PIO data port into dataPtr array. */
        for (indexx = i; indexx < i + MAX_ADDR_LINES; indexx++)
        {
#ifndef ALASKA
           readControlPort (baseAddr, (PIO_DATA_PORT), *(dataPtr+indexx));
#else
            readControlPort (baseAddr, (PIO_DATA_PORT), (dataPtr+indexx));
#endif
			VERY_SHORT_DELAY(10);
        }
    }

    return (HWAPI_PIO_WRITE_SUCCESS);
}

/********************************************************************************\
    Name       : bmePioBulkWrite
    Purpose    : To write data in bulk to BME through PIO interface.

    Parameters :
    no Name     Type        Description
    -- ----     ----        -----------
    1. bmeStruct    tBmeStruct* BME structure address
    2. destBaseAddr UINT32      destination address of where to write
    3. dataPtr  BYTE *      pointer to data to write
    4. numBytes UINT32      Number of bytes of data to write

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       HWAPI_PIO_WRITE_SUCCESS
\********************************************************************************/
HWAPI_RET_VAL bmePioBulkWrite (tBmeStruct *bmeStruct, UINT32 destBaseAddr, BYTE *dataPtr, UINT32 numBytes)
{
    BYTE *baseAddr;
    BYTE tempVal;
    UINT32 i, destAddr, indexx;


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

    destAddr = destBaseAddr;

#ifdef HIC_PIO_AUTO_INCR
    /* set the PIO addr Port with the destination address to transfer data to. */
    /* set this once outside the loop if address auto increment is available.  */
    for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
    {
        tempVal = (BYTE)((destAddr & (0xff000000 >> (indexx * 8))) >> ((MAX_ADDR_LINES - (indexx + 1)) * 8));
        writeControlPort (baseAddr, (PIO_ADDR_PORT), tempVal);
		VERY_SHORT_DELAY(10);
    }
#endif
    /* Loop for PIO write sequences, to store the data 4 bytes at a time */
    for (i = 0; i < numBytes; i += 4, destAddr += 4)
    {
#ifndef HIC_PIO_AUTO_INCR
        /* set the PIO addr Port with the destination address to transfer data to. */
        /* set this every time with manually incremented adderss if auto increment is not available  */
        for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
        {
            tempVal = (BYTE)((destAddr & (0xff000000 >> (indexx * 8))) >> ((MAX_ADDR_LINES - (indexx + 1)) * 8));
            writeControlPort (baseAddr, (PIO_ADDR_PORT), tempVal);
			VERY_SHORT_DELAY(10);
        }
#endif
        /* write the data from dataPtr to PIO data port. */
        for (indexx = i; indexx < i + MAX_ADDR_LINES; indexx++)
        {
            writeControlPort (baseAddr, (PIO_DATA_PORT), *(dataPtr+indexx));
			VERY_SHORT_DELAY(10);
        }
        /* set the Command Port to PIO write register command. */
#ifdef HIC_PIO_AUTO_INCR
        writeControlPort (baseAddr, (COMMAND_PORT), PIO_WRITE_REG_CMD);
        //writeControlPort (baseAddr, (COMMAND_PORT), PIO_WRITE_AUTO_INCR_REG_CMD);
#else
        writeControlPort (baseAddr, (COMMAND_PORT), PIO_WRITE_REG_CMD);
#endif
		VERY_SHORT_DELAY(10);
    }

    return (HWAPI_PIO_WRITE_SUCCESS);
}


#ifdef HIC_PIO_AUTO_INCR

HWAPI_RET_VAL bmePioReadNextLoc (tBmeStruct *bmeStruct, BYTE *dataPtr)
{
	BYTE *baseAddr;
	BYTE indexx;

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

	/* no need to set the PIO addr Port with the source address as this is with address auto-increment */

	/* set the Command Port to PIO read register command.
	The read data will be placed in PIO data port. */
	writeControlPort (baseAddr, (COMMAND_PORT), PIO_READ_REG_CMD);
	VERY_SHORT_DELAY(100);

	/* Read the data from PIO data port and put it in dataPtr being passed. */
	for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
	{
#ifndef ALASKA
		readControlPort (baseAddr, (PIO_DATA_PORT), *(dataPtr+indexx));
#else
		readControlPort (baseAddr, (PIO_DATA_PORT), (dataPtr+indexx));
#endif
		VERY_SHORT_DELAY(100);
	}

	return (HWAPI_PIO_READ_SUCCESS);
}

HWAPI_RET_VAL bmePioWriteNextLoc (tBmeStruct *bmeStruct, BYTE *dataPtr)
{
	BYTE *baseAddr;
	BYTE indexx;

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

	/* no need to set the PIO addr Port with the destination address as this is with address auto-increment */

	/* write the data from dataPtr to PIO data port. */
	for (indexx = 0; indexx < MAX_ADDR_LINES; indexx++)
	{
		writeControlPort (baseAddr, (PIO_DATA_PORT), *(dataPtr+indexx));
		VERY_SHORT_DELAY(100);
	}

	/* set the Command Port to PIO write register command. */
	writeControlPort (baseAddr, (COMMAND_PORT), PIO_WRITE_REG_CMD);
	VERY_SHORT_DELAY(100);

	return (HWAPI_PIO_WRITE_SUCCESS);
}
#endif //HIC_PIO_AUTO_INCR


/********************************************************************************\
    Name       : iposDelay
    Purpose    : To wait for a while.
    Parameters : None
    Return     : void
\********************************************************************************/
void iposDelay (void)
{
    int indexx;

    for (indexx = 0; indexx <= MAX_DELAY_COUNT; indexx++);

    return;
}

#ifdef CPE_40
static void hicInit(tBmeStruct *bmeStruct)
{
  UINT32 pio_isr_val = 0x100;

  bmeStruct->hicStatus = 0;

  bmePioWrite (bmeStruct, PIO_ISR(0), (BYTE *)&pio_isr_val);

  bmeClrStatus (bmeStruct, MSG_RDY_IN_BME_DPRAM);
}
#endif

/********************************************************************************\
    Name       : bmeSoftwareDnld
    Purpose    : To download software code to BME chip

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address
    2. dnldAddr       UINT32        mem address where the code is to be downloaded
    3. codeSize       UINT32        size of code to be downloaded
    4. pCodeData      BYTE *        ptr to code data to be downloaded

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       if dnld is successful, HWAPI_DNLD_SUCCESS
                        if error, HWAPI_DNLD_FAILURE, HWAPI_DNLD_TIMEOUT


\********************************************************************************/

HWAPI_RET_VAL bmeSoftwareDnld (tBmeStruct *bmeStruct)
{
    BYTE bTmpVal;
    UINT32 codeDnldAddr = 0, codeLen = 0;
    int dataLen = 0, iCounter1 = 0, iCounter2 = 0;
    int  totalWrLen = 0;

    codeLen = bmeStruct->BMECodeSize; /* 356044 */
    codeDnldAddr = bmeStruct->BMECodeDnldAddr;
//  bmeIntState[bmeStruct->BmeNum - 1] = 0;
#ifndef CPE_40
  bmeStruct->fifoStatus = FIFO_EMPTY;
#endif
  bmeStruct->msgRdyPending = FALSE;

  /*EventLog ("b%dp0 bmeSoftwareDnld: codeLen 0x%08lx 0x%08lx", bmeStruct->BmeNum,codeLen,codeDnldAddr);
*/

    /* transfer BME code through DMA interface - 256 bytes at a time */
    while (codeLen > 0)
    {
        /* delay between each block of write data */
        // iposTaskDelay (1);

        /* 256 or less than 256 bytes at a time */
        dataLen = (codeLen > (MAX_DATA_LENGTH+1)) ? (MAX_DATA_LENGTH+1) : codeLen;

        /* assign destination address & data length to write */
        bmeStruct->destAddr = codeDnldAddr;
        bmeStruct->dataLen = dataLen;
        //EventLog ("b%dp0 ...bmeSoftwareDnld: dataLen 0x%08lx 0x%08lx", bmeStruct->BmeNum,dataLen,codeDnldAddr);

        /* transmit data to BME memory */
        if (DoTxCmd(bmeStruct) != HWAPI_WRITE_SUCCESS)
        {
            iCounter1++;
            if (iCounter1 < MAX_WAIT_COUNT) /* wait for success for 16 times*/
                continue;
            else
            {
                //EventLog ("b%dp0 ...bmeSoftwareDnld: Error writing code into memory 0x%lx!", bmeStruct->BmeNum,codeDnldAddr);
                bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                return (HWAPI_DNLD_TIMEOUT);
            }
        }
        else
        {
            iCounter1 = 0;
            while (1)
            {
                /* wait for DW_H status bit to be set to indicate DMA Write is done */
                if (bmePollDmaStatus(bmeStruct) == DMA_DONE)
                {
                    iCounter2 = 0;
                    break;
                }
                else
                {
                    /* keep a counter or timer. If timer value times out the max
                    wait time, break from the loop & report a failure to the api.*/
                    iCounter2++;
                    if (iCounter2 < MAX_WAIT_COUNT) /* wait for 16/256 times */
                    {   iposDelay();

                    }
                    else
                    {
                        //EventLog ("b%dp0 ...bmeSoftwareDnld: Error dma not done while downloading BME code!",bmeStruct->BmeNum);
                        bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                        return (HWAPI_DNLD_TIMEOUT);
                    }
                }
            }

            /* if DW_T bit is set by DMA controller, change the BmeDnldVerifyState
            from DW_T_BIT_RESET to DW_T_BIT_SET */
            if (bmeStruct->BmeDnldVerifyState == DW_T_BIT_RESET)
            {
                /* read the DMA Status Port */
                bTmpVal = bmeRdStatus (bmeStruct);

                /* check the status[1] (DW_T) bit of DMA Status Port to be one.
               This indicates data is transferred from the fifo to BME memory. */
                if (bTmpVal & DW_T_DMA_WRITE_DONE)
                {
                    bmeStruct->BmeDnldVerifyState = DW_T_BIT_SET;
                }
            }

            /* This code reads back each block of written data & checks for written data validity.
               It compares each read byte with each write byte & gives an error, if both are not
               matching */
#if 0 // Aalska
            if (codeDnldAddr != BME_RESET_VEC_CODE_DNLD_ADDR)
            {
                if(bmeVerifyWriteCode (bmeStruct, codeDnldAddr, dataLen, (BYTE *)&BMECodeArray[totalWrLen]) != HWAPI_CODE_CHKSUM_SUCCESS)
                {
                    //EventLog ("b%d,p0 ...bmeSoftwareDnld: Error while reading data. TotalWrLen 0x%x\n", bmeStruct->BmeNum,totalWrLen+dataLen);
                    return (HWAPI_DNLD_FAILURE);
                }
            }
#endif

        }

        totalWrLen += dataLen; /* increment total write length */
        codeLen -= dataLen; /* decrement the code length to write */
        codeDnldAddr += dataLen; /* increment the code download addr */
        bmeStruct->dataPtr = &BMECodeArray[totalWrLen]; /* increment the bmeCodeArray pointer */
    }

    /*EventLog("b%dp0 bmeSoftwareDnld Rv HWAPI_DNLD_SUCCESS: %x State: %i",
            bmeStruct->BmeNum,bmeStruct->BmeState);*/

#ifndef CPE_40
  bmeStruct->fifoStatus = FIFO_EMPTY;
#endif
  bmeStruct->msgRdyPending = FALSE;

    return (HWAPI_DNLD_SUCCESS);

}

/********************************************************************************\
    Name       : bmeDnldProcedure
    Purpose    : To download software code to BME chip

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       if dnld is successful, HWAPI_DNLD_SUCCESS
                        if error, HWAPI_DNLD_FAILURE, HWAPI_DNLD_TIMEOUT


\********************************************************************************/
extern int bup_IFEPrgPLL ();
HWAPI_RET_VAL bmeDnldProcedure (tBmeStruct *bmeStruct)
{
    //EventLog("b%dp0 bmeDnldProcedure",bmeStruct->BmeNum);

  int i=0;
#ifdef  BME_CPE_20
#ifdef RMII_MODE
    HostFpgaWrite(7,2);             // for iKanos bringup board: reset/enable phy
#else
    HostFpgaWrite(7,6);             // for iKanos bringup board: reset/enable phy
#endif //RMII_MODE
#endif
    /* 1. release cpu - ReleaseBmeCpu - Inactive state */
    bmeRelCpu (bmeStruct,FALSE); /* hold BME cpu */

    /* Add BME speed change HERE */

    bmeHwResetApi(bmeStruct->BmeNum);
    // bup_IFEPrgPLL ();

#if defined(BME_CPE_20) && defined(INI_SUPPORT)
  iposPtmfReset();
#endif

    iposTaskDelay(10);

#ifndef NO_SET_PROD_MODE

#ifdef EIGHT_PORT_DB
    setProdMode (0);
#else
    setProdMode (1);
#endif
#endif

#if defined(CO_20_EMULATION_BOARD) || defined (CPE_40_EMULATION)
    taskDelay (100);
#endif
#if (defined CO_20 || defined CPE_40)
    /* Special set clock for CO 2.0 */
#ifndef ALASKA
    set_clkM(bmeStruct->BmeNum);
#endif
#else
#ifdef P2CO
#ifdef EIGHT_PORT_DB
    setclk(bmeStruct,131);
#else
    setclk(bmeStruct,157);
#endif
#else
 #ifndef    BME_CPE_20
    setclk(bmeStruct,140);
#endif
#endif
#endif

#if !defined(P2CO) && !defined(BME_CPE_20) && defined(INI_SUPPORT)
    fpgaHWReset();
#endif  // P2CO
#ifndef CPE_40
    /* 2. Initialize & program DMA channel 15 */
    InitDmaChannel15 (bmeStruct);
#endif
    //IK_PRINTF ("\nDma Channel 15 initialized");
    /* 3. Initialize & program the EMI interface */
    InitEMIConfig (bmeStruct);
    //IK_PRINTF ("\nEMI initialized");
    bup_IFEPrgPLL ();

#ifdef CPE_40
    hicInit (bmeStruct);
#endif

    /* 4. transfer BME code from host FLASH to BME memory */
    /* change BmeState from INACTIVE to SW_DNLD_IN_PROGRESS */
    if (bmeStruct->BmeState == INACTIVE)
        bmeStruct->BmeState = SW_DNLD_IN_PROGRESS;
    else
    {
        IK_PRINTF ("\nError downloading BME software 1!");
        return (HWAPI_DNLD_FAILURE);
    }
#ifdef CPE_40  // NUCLEUS
    BmeResetVecCode[4] = 0x40;
    BmeResetVecCode[5] = 1;
    BmeResetVecCode[6] = 0;
    BmeResetVecCode[7] = 0x60;
#else
    /* Set jump address in reset vector */
    BmeResetVecCode[4]=BMECodeArray[8];
    BmeResetVecCode[5]=BMECodeArray[9];
    BmeResetVecCode[6]=BMECodeArray[10];
    BmeResetVecCode[7]=BMECodeArray[11];
#endif

    /*IK_PRINTF ("\n BmeResetVecCode[4] %x",BmeResetVecCode[4]);
    IK_PRINTF ("\n BmeResetVecCode[5] %x",BmeResetVecCode[5]);
    IK_PRINTF ("\n BmeResetVecCode[6] %x",BmeResetVecCode[6]);
    IK_PRINTF ("\n BmeResetVecCode[7] %x",BmeResetVecCode[7]);*/


    /* set the BME code size & download address - for BME reset vector code */
    bmeStruct->BMECodeSize = BME_RESET_VEC_CODE_SIZE; /* 16 */
    bmeStruct->BMECodeDnldAddr = BME_RESET_VEC_CODE_DNLD_ADDR;
    bmeStruct->dataPtr = &BmeResetVecCode[0];

    if (bmeSoftwareDnld(bmeStruct) != HWAPI_DNLD_SUCCESS)
    {
        IK_PRINTF ("\nError downloading BME software 2!");
        return (HWAPI_DNLD_FAILURE);
    }
    else
    //EventLog ("\nb%ip0 Reset vector code downloaded successfully",bmeStruct->BmeNum);

    /* set the BME code size & download address */
    bmeStruct->BMECodeSize =sizeof (BMECodeArray);
#ifdef CPE_40 /// NUCLEUS
    bmeStruct->BMECodeDnldAddr = 0x40010060;
#else
    bmeStruct->BMECodeDnldAddr = BME_CODE_DNLD_ADDR;
#endif
    bmeStruct->dataPtr = &BMECodeArray[0];
    wrCount = 0;
    rdCount = 0;

    IK_PRINTF ("\nDownloading BME %x software..... ",bmeStruct->BmeNum);
    if (bmeSoftwareDnld(bmeStruct) != HWAPI_DNLD_SUCCESS)
    {
        IK_PRINTF ("\nError downloading BME software 3!");
        return (HWAPI_DNLD_FAILURE);
    }

    IK_PRINTF ("\nBme %x software code downloaded successfully",bmeStruct->BmeNum);

#if 0
    /* verify code check sum */
    if (bmeVerifyCodeDnld(bmeStruct) != HWAPI_CODE_CHKSUM_SUCCESS)
    {
        IK_PRINTF("\nError verifying code download!");
        return (HWAPI_DNLD_FAILURE);
    }

    IK_PRINTF ("\nBme %x software code verified successfully",bmeStruct->BmeNum);
#endif

    /* change the BmeState from SW_DNLD_IN_PROGRESS to SW_DNLD_DONE */
    bmeStruct->BmeState = SW_DNLD_DONE;
    bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];

#if defined(CO_20_EMULATION_BOARD) || defined (CPE_40_EMULATION)
    IK_PRINTF("\n**************** release cpu ****************\n");
    IK_PRINTF("****************  press key ****************\n");
    getchar ();
    bmeReleased = 1;
#elif defined(CO_50_EMULATION_BOARD)
    bmeReleased = 1;
    bmeRelCpu (bmeStruct,TRUE);   /*release BME cpu */
#else
#ifdef CPE_40_DIAGS
    if (!diagsHoldCpuInReset)
#endif
    /* 5. release cpu - ReleaseBmeCpu - active state */
    bmeRelCpu (bmeStruct,TRUE);   /*release BME cpu */
#endif

#ifdef HOST_INTERRUPT
    bmeIntEnable (bmeStruct,MSG_RDY_IN_BME_DPRAM_INTR);
#endif
    /* EventLog("b%dp0 Rv HWAPI_DNLD_SUCCESS: %x State: %i",
            bmeStruct->BmeNum,bmeStruct->BmeState);*/

    return (HWAPI_DNLD_SUCCESS);
}

/********************************************************************************\
    Name       : calculateCodeCheckSum
    Purpose    : To calculate the BME code checksum
    Parameters : None
    Return     :
    Type                Description
    ----                -----------
    UINT32          calculated 2's complement checksum

\********************************************************************************/

UINT32 calculateCodeCheckSum (void)
{
    UINT32 indexx;
    UINT32 chkSum = 0;

    for (indexx = 0; indexx < sizeof (BMECodeArray); indexx++)
    {
        /* sum of 1's complement of Bme code */
        chkSum += ~(BMECodeArray[indexx]);
    }

    //IK_PRINTF ("\nCalculated CheckSum %lx", chkSum);

    /* 2's complement of Bme code */
    chkSum = ~(chkSum);

    //IK_PRINTF ("\nCalculated CheckSum complement %lx\n", chkSum);

    return chkSum;
}

/********************************************************************************\
    Name       : bmeVerifyWriteCode
    Purpose    : To verify the downloaded software code to BME chip (1 block at a time)

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address
    2. codeDnldAddr   UINT32        Memory address where the code is downloaded into BME
    3. codeLen        UINT32        Length of the downloaded code
    4. BmeCodeArrayPtr BYTE*        Pointer to BME Code Array

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       if verification is successful, HWAPI_CODE_CHKSUM_SUCCESS
                        if error, HWAPI_CODE_CHKSUM_TIMEOUT, HWAPI_CODE_CHKSUM_FAILED

\********************************************************************************/

HWAPI_RET_VAL bmeVerifyWriteCode (tBmeStruct *bmeStruct, UINT32 codeDnldAddr, UINT32 codeLen, BYTE *BmeCodeArrayPtr)
{
    int dataLen = 0, iCounter1 = 0, iCounter2 = 0;
    int indexx = 0;

    /* assign dataPtr with BmeMsg structure. This is where data is read into */
    bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];

    /* transfer BME code through DMA interface - 256 bytes at a time */
    while (1)
    {
        /* read 256 or less than 256 bytes of data */
        dataLen = (codeLen > (MAX_DATA_LENGTH+1)) ? (MAX_DATA_LENGTH+1) : codeLen;

        /* assign source address & data length to read */
        bmeStruct->srcAddr = codeDnldAddr;
        bmeStruct->dataLen = dataLen;

        /* delay between each block of read data */
        iposTaskDelay (1);

        /* initiate data transfer from BME memory to HIC_FIFO */
        if (DoTrCmd(bmeStruct) != HWAPI_TRANSFER_SUCCESS)
        {
            iCounter1++;
            if (iCounter1 < MAX_WAIT_COUNT) /* wait for success for 16 times*/
                continue;
            else
            {
                IK_PRINTF ("\nError reading code from memory!");
                bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                return (HWAPI_CODE_CHKSUM_TIMEOUT);
            }
        }
        else
        {
            iCounter1 = 0;
            while (1)
            {
                /* check for DW_H status bit to be set to indicate DMA read is done */
                if (bmePollDmaStatus(bmeStruct) == DMA_DONE)
                {
                    iCounter2 = 0;
                    break;
                }
                else
                {
                    /* keep a counter or timer. If timer value times out the max
                    wait time, break from the loop & report a failure to the api.*/
                    iCounter2++;
                    if (iCounter2 < MAX_WAIT_COUNT) /* wait for 16/256 times */
                        iposDelay();
                    else
                    {
                        IK_PRINTF ("\nError dma not done while downloading BME code! count %d", iCounter2);
                        bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                        return (HWAPI_CODE_CHKSUM_TIMEOUT);
                    }
                }
            }

            /* if DW_H bit is set by DMA controller, ready to read data */
            if (DoRdCmd(bmeStruct) != HWAPI_READ_SUCCESS)
            {
                iCounter1++;
                if (iCounter1 < MAX_WAIT_COUNT) /* wait for success for 16 times*/
                    continue;
                else
                {
                    IK_PRINTF ("\nError reading code from memory!");
                    bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                    return (HWAPI_CODE_CHKSUM_TIMEOUT);
                }
            }
            else
            {
                iCounter1 = 0;
                /* after reading one block of data, compare each & every byte of data with the
                actual written data. If both are not matching, some error while writing/reading.
                give error message & stop downloading code */
                for (indexx = 0; indexx < bmeStruct->dataLen; indexx++)
                {
                    if (bmeStruct->BmeMsg[indexx] == *(BmeCodeArrayPtr+indexx))
                        continue;
                    else
                    {
                        IK_PRINTF ("\nindexx 0x%x, Expected byte 0x%02x, Read byte 0x%02x",
                            indexx, *(BmeCodeArrayPtr+indexx), bmeStruct->BmeMsg[indexx]);
                        return (HWAPI_CODE_CHKSUM_FAILED);
                    }
                }
            }
        }
        break;
    }

    return (HWAPI_CODE_CHKSUM_SUCCESS);
}

/********************************************************************************\
    Name       : bmeReadDnldCode
    Purpose    : To read the downloaded software code to BME chip for verification

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address
    2. codeChkSum     UINT32        calculated software code checksum

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       if verification is successful, HWAPI_CODE_CHKSUM_SUCCESS
                        if error, HWAPI_CODE_CHKSUM_TIMEOUT, HWAPI_CODE_CHKSUM_FAILED

\********************************************************************************/

HWAPI_RET_VAL bmeReadDnldCode (tBmeStruct *bmeStruct, UINT32 codeChkSum)
{
    UINT32 codeDnldAddr = 0, codeLen = 0;
    int dataLen = 0, iCounter1 = 0, iCounter2 = 0;
    int indexx = 0;

    /* assign the total code length to read & the starting code Download address of BME to read */
    codeLen = bmeStruct->BMECodeSize; /* 356044 */
    codeDnldAddr = bmeStruct->BMECodeDnldAddr;

    /* assign the dataPtr with BmeMsg structure, where the read data will be stored during every
    block read */
    bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];

    /* get the complement of 2's complement of sum chksum == 1's complement of the sum checksum of all data */
    codeChkSum = ~codeChkSum;

    /* transfer BME code through DMA interface - 256 bytes at a time */
    while (codeLen > 0)
    {
        /* read 256 or less than 256 bytes of data */
        dataLen = (codeLen > (MAX_DATA_LENGTH+1)) ? (MAX_DATA_LENGTH+1) : codeLen;

        /* assign data length & source address to read */
        bmeStruct->srcAddr = codeDnldAddr;
        bmeStruct->dataLen = dataLen;

        /* delay between every block of read */
        iposTaskDelay (1);

        /* initiate transfer of data from BME memory to HIC_FIFO */
        if (DoTrCmd(bmeStruct) != HWAPI_TRANSFER_SUCCESS)
        {
            iCounter1++;
            if (iCounter1 < MAX_WAIT_COUNT) /* wait for success for 16 times*/
                continue;
            else
            {
                IK_PRINTF ("\nError reading code from memory!");
                bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                return (HWAPI_CODE_CHKSUM_TIMEOUT);
            }
        }
        else
        {
            iCounter1 = 0;
            while (1)
            {
                /* check for DW_H status bit to be set to indicate DMA read is done */
                if (bmePollDmaStatus(bmeStruct) == DMA_DONE)
                {
                    iCounter2 = 0;
                    break;
                }
                else
                {
                    /* keep a counter or timer. If timer value times out the max
                    wait time, break from the loop & report a failure to the api.*/
                    iCounter2++;
                    if (iCounter2 < MAX_WAIT_COUNT) /* wait for 16/256 times */
                        iposDelay();
                    else
                    {
                        IK_PRINTF ("\nError dma not done while downloading BME code!");
                        bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                        return (HWAPI_CODE_CHKSUM_TIMEOUT);
                    }
                }
            }

            /* if DW_H bit is set by DMA controller, ready to read data */
            if (DoRdCmd(bmeStruct) != HWAPI_READ_SUCCESS)
            {
                iCounter1++;
                if (iCounter1 < MAX_WAIT_COUNT) /* wait for success for 16 times*/
                    continue;
                else
                {
                    IK_PRINTF ("\nError reading code from memory!");
                    bmeStruct->dataPtr = &bmeStruct->BmeMsg[0];
                    return (HWAPI_CODE_CHKSUM_TIMEOUT);
                }
            }
            else
            {
                iCounter1 = 0;
                /* each time, after reading 1 block, decrement the 1's complement of each byte from the
                1's complement sum checksum */
                for (indexx = 0; indexx < bmeStruct->dataLen; indexx++)
                    codeChkSum -= ~bmeStruct->BmeMsg[indexx];

                /* IK_PRINTF ("\nChksum 0x%lx", codeChkSum); */
            }

        }

        /* decrement the code length & increment the code download address to read */
        codeLen -= dataLen;
        codeDnldAddr += dataLen;
    }

/*  EventLog("b%dp0 bmeSoftwareDnld Rv HWAPI_CODE_CHKSUM_SUCCESS: %x State: %i",
            bmeStruct->BmeNum,bmeStruct->BmeState);*/

    //IK_PRINTF ("\nReadDnld check sum 0x%lx", codeChkSum);

    /* if zero checksum, downloaded code is valid */
    if (!codeChkSum)
        return (HWAPI_CODE_CHKSUM_SUCCESS);
    /* else downloaded code has errors */
    else
        return (HWAPI_CODE_CHKSUM_FAILED);

}

/********************************************************************************\
    Name       : verifyCodeCheckSum
    Purpose    : Sample program to verify the BME code checksum
    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. chkSum           UINT32      calculated 2's complement checksum

    Return     :
    Type                Description
    ----                -----------
    BYTE                if verification is successful, i.e., if chkSum is zero, TRUE
                        else FALSE

\********************************************************************************/

BYTE verifyCodeCheckSum (UINT32 chkSum)
{
    UINT32 indexx;

    /* get 1's complement of sum checksum of data */
    chkSum = ~(chkSum);

    /* decrement 1's complement of each byte from the 1's complement sum checksum of data */
    for (indexx = 0; indexx < BME_CODE_SIZE; indexx++)
    {
        chkSum -= ~(BMECodeArray[indexx]);
    }

    IK_PRINTF ("\nVerified CheckSum %lx\n", chkSum);

    /* if zero checksum, data is valid */
    if (!chkSum)
        return TRUE;
    /* else data is not valid */
    else
        return FALSE;
}


/********************************************************************************\
    Name       : bmeVerifyCodeDnld
    Purpose    : To verify the BME software code download (all blocks at a time)
    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       if verification is successful, HWAPI_CODE_CHKSUM_SUCCESS
                        if error, HWAPI_CODE_CHKSUM_TIMEOUT, HWAPI_CODE_CHKSUM_FAILED

\********************************************************************************/

HWAPI_RET_VAL bmeVerifyCodeDnld (tBmeStruct *bmeStruct)
{
    HWAPI_RET_VAL retVal;
    UINT32 chkSum;

    /* calculate the code checksum from BmeCodeArray */
    chkSum = calculateCodeCheckSum ();

    /* try to match the calculated checksum with the sum checksum of all the blocks of read data */
    retVal = bmeReadDnldCode (bmeStruct, chkSum);

    return(retVal);
}



/*** Below are user-defined functions called by host APIs ***/
/*** Requirements of functions are in iPOS datasheet ***/


/****************************************************************************/
/*                                                                          */
/* Function.. : bmeRelCpu( )                                                */
/*                                                                          */
/* Purpose... : Holds or releases BME CPU                                   */
/*                                                                          */
/* Parameters : unsigned char - enable. If enable is 1, releases BME CPU.   */
/*              Else holds BME CPU.                                         */
/*                                                                          */
/* Returns... : N/A                                                         */
/*                                                                          */
/* Notes..... : None                                                        */
/*                                                                          */
/****************************************************************************/
void bmeRelCpu (tBmeStruct *pBme,unsigned char enable)
{
    if (pBme->BmeNum==1)
    {
        if (enable)
            relBmeCpu (TRUE);
        else
            relBmeCpu (FALSE);
    }
    else
    {
        relCpu(pBme->BmeNum,enable);
    }
}
/********************************************************************************\
    Name       : pollForDwTBitToBeCleared
    Purpose    : To poll the DMA status port & to verify whether the DW_T bit is
                 cleared by Tensilica processor. This is used to indicate whether
                 BME software download is proper & the integrity of the software
                 is verified. Tensilica would clear this DW_T bit only if the BME
                 is up & running.

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1.      pBme      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    eBmeRv              1. if success, DMA_DONE
                        2. if not success, DMA_NOT_DONE
\********************************************************************************/
eBmeRv pollForDwTBitToBeCleared (tBmeStruct *pBme)
{
    BYTE bDmaStatus;
    UINT32 bPollCount=0;

    while (1)
    {
        /* read the DMA status port */
        bDmaStatus = bmeRdStatus (pBme);
        bPollCount++;

        /* check if DW_T bit is cleared */
        if (!(bDmaStatus & DW_T_DMA_WRITE_DONE))
        {
            return DMA_DONE;
        }

        else
        {
            if (bPollCount < 5000)  /* poll for 16 times ? */
            {

                iposTaskDelay(5);
                continue;
            }
            else
            {
            /*  EventLog ("b%dp0 pollForDwTBitToBeCleared Fail: bDmaStatus %x DW_T bit not cleared. Time out occured"
                    ,pBme->BmeNum,bDmaStatus);*/
                return DMA_NOT_DONE;
            }
        }
    } /* while (1) */
}


/*** Higher level functions that call HW APIs ***/

/********************************************************************************\
    Name       : DoTxCmd
    Purpose    : To transmit a BME message to BME dpram or to any BME memory through
                 DMA FIFO interface (256 bytes per transaction).

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       1. if success, HWAPI_WRITE_SUCCESS
                        2. if error, HWAPI_FAILED, HWAPI_FAILURE_FIFO_NOT_AVAILABLE
\********************************************************************************/

 HWAPI_RET_VAL DoTxCmd (tBmeStruct *bmeStruct)
{
    HWAPI_RET_VAL retVal=HWAPI_FAILED;

/*  EventLog("b%dp0 ...DoTxCmd fifoStatus=%x msgRdyPending=%x ",
           bmeStruct->BmeNum, bmeStruct->fifoStatus, bmeStruct->msgRdyPending);*/
#ifdef CPE_40
    retVal = bmeWrMemory (bmeStruct, bmeStruct->destAddr, bmeStruct->dataPtr, bmeStruct->dataLen);
#else
    if ((bmeStruct->fifoStatus == FIFO_EMPTY) &&
      (bmeStruct->msgRdyPending == FALSE))
    {
        /* lock interrupts */
        /* lock preemption */

        /* Only for DEBUG-FIFO to memory:bmeStruct->FifoFlag=1;*/

        bmeStruct->fifoStatus = FIFO_WRITE_IN_PROGRESS;
        if (bmeStruct->destAddr == DPRAM_BASE_ADDR)
            //retVal = bmeWrMessage (bmeStruct, (BYTE *)bmeStruct->BmeMsg, bmeStruct->dataLen);
                retVal = bmeWrMemory (bmeStruct, bmeStruct->destAddr, bmeStruct->dataPtr, bmeStruct->dataLen);
        else
            retVal = bmeWrMemory (bmeStruct, bmeStruct->destAddr, bmeStruct->dataPtr, bmeStruct->dataLen);

        if (retVal == HWAPI_WRITE_SUCCESS)
            bmeStruct->fifoStatus = FIFO_WRITE;
        else
            retVal = HWAPI_FAILED;

        /* unlock preemption */
        /* unlock interrupts */
    }
    else
    {
        /* FIFO is not empty and message in FIFO is not meant to be read */
        retVal = HWAPI_FAILURE_FIFO_NOT_AVAILABLE;
    }

    if (retVal != HWAPI_WRITE_SUCCESS)
        bmeStruct->fifoStatus = FIFO_EMPTY;

#endif
    return (retVal);
}

/********************************************************************************\
    Name       : DoInvokeRead
    Purpose    : This function invokes transfer message or read message of BME
                 accordingly, depending upon the fifostatus.

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       1. if success, HWAPI_TRANSFER_SUCCESS / HWAPI_READ_SUCCESS
                        2. if error, HWAPI_FAILED, HWAPI_FAILURE_FIFO_NOT_AVAILABLE
\********************************************************************************/

#ifndef CPE_40
 HWAPI_RET_VAL DoInvokeRead (tBmeStruct *bmeStruct)
{
    HWAPI_RET_VAL retVal=HWAPI_FAILED;

    if ((bmeStruct->fifoStatus == FIFO_EMPTY) &&
      (bmeStruct->msgRdyPending == TRUE))
        return(DoTrCmd (bmeStruct));

    if (bmeStruct->fifoStatus == FIFO_READ)
        return(DoRdCmd (bmeStruct));

    return (retVal);
}
#endif

/********************************************************************************\
    Name       : DoTrCmd
    Purpose    : To transfer the BME message from BME dpram or from any memory to
                 DMA fifo ( 256 bytes max ).

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
                    HWAPI_RET_VAL       1. if success, HWAPI_TRANSFER_SUCCESS
                        2. if error, HWAPI_FAILED
\********************************************************************************/

 HWAPI_RET_VAL DoTrCmd (tBmeStruct *bmeStruct)
{
    HWAPI_RET_VAL retVal=HWAPI_FAILED;

#ifdef CPE_40
    retVal = HWAPI_TRANSFER_SUCCESS;
    if (bmeStruct->srcAddr == DPRAM_BASE_ADDR)
    {
        if (bmeStruct->msgRdyPending == TRUE) {
                bmeStruct->srcAddr=DPRAM_TX_BASE_ADDR;
                bmeStruct->dataLen=0xff;
        } else
            retVal = HWAPI_FAILED;
    }
#else
    if (bmeStruct->fifoStatus == FIFO_EMPTY)
    {
        /* lock interrupts */
        /* lock preemption */

        bmeStruct->fifoStatus = FIFO_READ_IN_PROGRESS;

        if (bmeStruct->srcAddr == DPRAM_BASE_ADDR)
        {
            if (bmeStruct->msgRdyPending == TRUE)
                {
                bmeStruct->srcAddr=DPRAM_TX_BASE_ADDR;
                bmeStruct->dataLen=0xff;
                bmeStruct->FifoFlag=0;

                /*retVal = bmeTrMessage (bmeStruct);*/
                retVal = bmeTrMemory (bmeStruct, bmeStruct->srcAddr, bmeStruct->dataLen);

                }
            else
                retVal = HWAPI_FAILED;
        }
        else
            retVal = bmeTrMemory (bmeStruct, bmeStruct->srcAddr, bmeStruct->dataLen);

        if (retVal != HWAPI_TRANSFER_SUCCESS)
            retVal = HWAPI_FAILED;

        /* unlock preemption */
        /* unlock interrupts */
    }
    else
        retVal = HWAPI_FAILED;

    if (retVal != HWAPI_TRANSFER_SUCCESS)
        bmeStruct->fifoStatus = FIFO_EMPTY;
#endif
    return (retVal);
}

/********************************************************************************\
    Name       : DoRdCmd
    Purpose    : To read the BME message from BME DMA fifo & to store it in
                 InBmeMsg in bme structure.

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1. bmeStruct      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    HWAPI_RET_VAL       1. if success, HWAPI_READ_SUCCESS
                        2. if error, HWAPI_FAILED
\********************************************************************************/
 HWAPI_RET_VAL DoRdCmd (tBmeStruct *bmeStruct)
{
    HWAPI_RET_VAL retVal=HWAPI_FAILED;
#ifndef CPE_40
    if (bmeStruct->fifoStatus == FIFO_READ)
    {
        /* lock interrupts */
        /* lock preemption */
#endif
        if (bmeStruct->srcAddr == DPRAM_BASE_ADDR)
            /*retVal = bmeRdMessage (bmeStruct, (BYTE *)bmeStruct->RxBmeMsg);*/
            retVal = bmeRdMemory (bmeStruct, (BYTE *)bmeStruct->RxBmeMsg);
        else
            retVal = bmeRdMemory (bmeStruct, (BYTE *)bmeStruct->BmeMsg);

        if (retVal == HWAPI_READ_SUCCESS)
        {
            /* Message successfully read. Clear all status flags */
#ifndef CPE_40
            bmeStruct->fifoStatus = FIFO_EMPTY;
#endif
            bmeStruct->msgRdyPending = FALSE;
        }
        else
            retVal = HWAPI_FAILED;

            /* unlock preemption */
            /* unlock interrupts */
#ifndef CPE_40
    }
    else {
        retVal = HWAPI_FAILED;
        IK_PRINTF("DoRdCmd FAIL:fifo_status = %d\n", bmeStruct->fifoStatus);
    }
#endif
    return (retVal);
}

/********************************************************************************\
    Name       : bmePollDmaStatus
    Purpose    : To poll the DMA status port & to verify whether the DMA read
                 or transfer or write transcation is completed. If transaction is
                 completed, change the fifostatus & set the required flags
                 appropriately.

    Parameters :
    no      Name        Type            Description
    --      ----        ----            -----------
    1.      pBme      tBmeStruct*   BME structure address

    Return     :
    Type                Description
    ----                -----------
    eBmeRv              1. if success, DMA_DONE
                        2. if not success, DMA_NOT_DONE
\********************************************************************************/
eBmeRv bmePollDmaStatus (tBmeStruct *pBme)
{
#ifdef CPE_40
	pBme++;
    return DMA_DONE;
#else
    BYTE bDmaStatus;
    /* read the DMA status port */
    bDmaStatus = bmeRdStatus (pBme);

    /* check if it is DMA_WRITE_DONE interrupt */
    if (bDmaStatus & DW_H_DMA_WRITE_DONE)
    {
        if (pBme->fifoStatus == FIFO_WRITE)
        {
            /* if clearing of the dma status bit is required for every message,
            send host acknowledge */
            bmeClrStatus (pBme, CLR_DW_H_DMA_WRITE_DONE);

            /* reset the FIFO status */
            pBme->fifoStatus = FIFO_EMPTY;
        }
        else if (pBme->fifoStatus == FIFO_READ_IN_PROGRESS)
        {
            pBme->fifoStatus = FIFO_READ;
        }

//      EventLog ("b%dp0 ...bmePollDmaStatus DMA_DONE status 0x%x",pBme->BmeNum,bDmaStatus);
        return DMA_DONE;
    }

    else
    {
        //EventLog ("b%dp0 ...bmePollDmaStatus DMA_NOT_DONE status 0x%x",pBme->BmeNum,bDmaStatus);
        return DMA_NOT_DONE;
    }
#endif
/*  return (bmeDmaTransactionCompletion (pBme)); */
}

void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data);

void setclk (tBmeStruct *pBme, int num)
{
    unsigned long val;

    switch (num)
        {
        case 50:
            val = 0x11b;
            break;
        case 96:
            val = 0x12f;
            break;
        case 105:
            val = 0x133;
            break;
        case 113:
            val = 0x137;
            break;
        case 122:
            val = 0x13b;
            break;
        case 131:
            val = 0x13f;
            break;
        case 140:
            val = 0x143;
            break;
        case 148:
            val = 0x147;
            break;
        case 157:
            val = 0x14b;
            break;
        case 166:
            val = 0x14f;
            break;
                case 175:
            val = 0x153;
            break;
        case 183:
            val = 0x157;
            break;
        case 192:
            val = 0x15b;
            break;
        case 201:
            val = 0x15f;
            break;
        case 210:
            val = 0x163;
            break;


        default:
            IK_PRINTF("Invalid value %d\n", num);
            return;


        }

    bmePioWrite (pBme, 0xe0070008, (BYTE *)&val);


}


// HIC Status bit polling functions

#ifndef CPE_40
int pollTxMsgReady (tBmeStruct *pBme)
{
    BYTE bDmaStatus = 0;
    int data=0;

    /* read DMA_STATUS_PORT */
    bDmaStatus = bmeRdStatus (pBme);

    /* check if it is DMA_WRITE_DONE interrupt */
    if ((bDmaStatus & DW_H_DMA_WRITE_DONE) && ((bDmaStatus & DW_T_DMA_WRITE_DONE)==0))
    {
        pBme->fifoStatus = FIFO_WRITE;

        /* if set, clear the status */
        bmeClrStatus (pBme, CLR_DW_H_DMA_WRITE_DONE);

        pBme->fifoStatus=FIFO_EMPTY;

        data = 0x00000000;
        bmePioWrite (pBme, DMA_CCR(0, DMA_CH_15), (BYTE *)&data);
        return TRUE;
    } else
    {
        return FALSE;
    }

}

#endif

int pollRxMsgReady (tBmeStruct *pBme)
{
    BYTE bDmaStatus = 0;

    /* read DMA_STATUS_PORT */
    bDmaStatus = bmeRdStatus (pBme);

    /* check if it is DMA_WRITE_DONE interrupt */
    if (bDmaStatus & MSG_RDY_IN_BME_DPRAM)
    {
        pBme->msgRdyPending=TRUE;               /* Rx Ready: set Pending */
        return TRUE;
    } else
    {
        return FALSE;
    }
}

int pollDmaDone (tBmeStruct *pBme)
{
    UINT32 pio_isr_val;
#ifdef CPE_40
    // in CPE_40, pollDmaDone is used only for throttling Host to Bme messages
    // to ensure that Host does not overwrite its messages before the BME
    // has processed them.
    // The Receive path (Bme to host msgs) should not wait for a DMA complete
    // indication betn TransferBmeMessage and ReceiveBmeMessage, as there is
    // no HIC DMA anymore. So the actual copy happens in ReceiveBmeMessage
    // and TransferBmeMessage is a dummy.
    //if (pBme->fifoStatus != FIFO_READ || pBme->fifoStatus != FIFO_READ_IN_PROGRESS)
    //{
        bmePioRead  (pBme, PIO_ISR(0), (BYTE *)&pio_isr_val);
        if (pio_isr_val & (1 << 8))
            return FALSE;
        else
            return TRUE;
    //}
#else
		BYTE bDmaStatus = 0;

    /* read DMA_STATUS_PORT */
    bDmaStatus = bmeRdStatus (pBme);

    /* check if it is DMA_WRITE_DONE interrupt */
    if (bDmaStatus & DW_H_DMA_WRITE_DONE)
    {
        if (pBme->fifoStatus == FIFO_READ_IN_PROGRESS)
            // Read transaction
            pBme->fifoStatus = FIFO_READ;
        else
        {
            // Transmit transaction
            pBme->fifoStatus=FIFO_EMPTY;
            /* if set, clear the status */
            bmeClrStatus (pBme, CLR_DW_H_DMA_WRITE_DONE);
        }

        return TRUE;
    } else
    {
        //pBme->fifoStatus=FIFO_EMPTY;
        return FALSE;
    }
#endif
}


HWAPI_RET_VAL TransferBmeMessage(tBmeStruct *pBme)
{

    HWAPI_RET_VAL   HwiApiRv=HWAPI_FAILED;

    /* Transfer message from DPRAM to FIFO
    Need to define  1) source address in BME structure
                    2) data length <--not anymore */

    pBme->srcAddr=DPRAM_BASE_ADDR;  /* Set flag to indicate DPRAM source */
    pBme->dataPtr=&(pBme->RxBmeMsg[0]);
#ifdef CPE_40
    if (pBme->msgRdyPending == TRUE)
        HwiApiRv=DoTrCmd (pBme);
#else
    pBme->FifoFlag=0;

    if ((pBme->fifoStatus == FIFO_EMPTY) &&
        (pBme->msgRdyPending == TRUE))
    {
        HwiApiRv=DoTrCmd (pBme);

        if (HwiApiRv==HWAPI_TRANSFER_SUCCESS)
            pBme->fifoStatus = FIFO_READ_IN_PROGRESS;
    }
   else
    {
        IK_PRINTF ("\nTransferBmeMessage fifoStatus not FIFO_EMPTY %d",pBme->fifoStatus);
    }
#endif
    return(HwiApiRv);
}

#if 1

#define MAX_BYTES_PER_LINE       16

#define MAXLINE         80  /* max line length for input to 'm' routine */
#define MAX_DSP_TASKS   500 /* max tasks that can be displayed */
#define MAX_DATE_STRING 21  /* dates have 21 characters */
void D
    (
    int bupbme,
    void *adrs,    /* address to display (if 0, display next block */
    int nunits,     /* number of units to print (if 0, use default) */
    int width       /* width of displaying unit (1, 2, 4, 8) */
    )
    {
    static dNitems = 0x40;  /* default number of item to display */
    static dWidth  = 4;     /* default width */
    static void *last_adrs = 0; /* last location displayed */

    int item;      /* item counter displayed per line */
    char ascii [MAX_BYTES_PER_LINE + 1]; /* ascii buffer for displaying */
    int ix;         /* temporary count */
    UINT8 byte;     /* byte pointer for filling ascii buffer */
    UINT32 tmpLong;      /* temporary long word pointer */

    ascii [MAX_BYTES_PER_LINE] = EOS;   /* put an EOS on the string */

    if (nunits == 0)
    nunits = dNitems;   /* no count specified: use default count */
    else
    dNitems = nunits;   /* change default count */

    width = dWidth;

    if (adrs == 0)      /* no address specified: use last address */
        adrs = last_adrs;
    else
        last_adrs = adrs;

    /* round address down to appropriate boundary */

    last_adrs = (void *)((int) last_adrs & ~(width - 1));

    /* print leading spaces on first line */

    memset (ascii, '.', 16);

    IK_PRINTF ("%08x:  ", (int) last_adrs & ~0xf);

    for (item = 0; item < ((int) last_adrs & 0xf) / width; item++)
    {
    IK_PRINTF ("%*s ", 2*width, " ");
    memset (&ascii[item * width], ' ', 2*width);
    }

    /* print out all the words */

    while (nunits-- > 0)
    {
    if (item == MAX_BYTES_PER_LINE/width)
        {
        /* end of line:
         *   print out ascii format values and address of next line */

        IK_PRINTF ("  *%16s*\n%08x:  ", ascii, (unsigned int) last_adrs);
        memset (ascii, '.', MAX_BYTES_PER_LINE); /* clear out ascii buffer */
        item = 0;               /* reset word count */
        }
        tmpLong = testPIORead1 (bupbme,(UINT32)last_adrs);
        IK_PRINTF ("%08lx", (UINT32)tmpLong);
        IK_PRINTF (" ");   /* space between words */

    /* set ascii buffer */

        for (ix = 0; ix < width; ix ++)
        {
            byte = (tmpLong >> (ix*4)) & 0xff;
            if (byte == ' ' || (isascii (byte) && isprint (byte)))
            {
                ascii[item*width +3-ix] = byte;
            }
        }

    last_adrs = (void *)((int)last_adrs + width);
    item++;
    }

    /* print remainder of last line */

//    for (; item < MAX_BYTES_PER_LINE/width; item++)
//      IK_PRINTF ("%*s ", 2*width, " ");

//    IK_PRINTF ("  *%16s*\n", ascii); /* print out ascii format values */
        IK_PRINTF("\n");
    }
#endif

/* END OF FILE */
