/**************************************************************
$Workfile:   bme_mon.c  $
***************************************************************
**
** Host Code, 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 $
***************************************************************/

/*******  Include Files         ***************************************/

#include <stdio.h>
#include <stdlib.h>

#include "ipos.h"
#include "dapi.h"
#include "apilocal.h"
#include "bmeconfig.h"
#include "apiosmacro.h"

/*******  Defines               ***************************************/
#define MAX_ITEM_IN_LINE	(3)
#define MAX_BME				IPOS_MAX_BME
#define u8 U8
#define u16 U16
#define uint16 U16
#define u32 U32
#define s16 S16
#define s32 S32

#define LOCAL_WDM_BUFF_SIZE	(0x2000)
#define LOCAL_BUFF_SIZE		(2*16388)

#define BME_Mon_InsertNewLine_M(j)\
{\
	if ( j < MAX_ITEM_IN_LINE )\
	{\
		j++;\
	}\
	else\
	{\
		printf("\n");\
		j = 0;\
	}\
}
/*******  Constants             ***************************************/
extern tBmeStruct  	BmeStruct[];	  		 /* BME objects for direct API */

/*******  Local Data Structures ***************************************/

/*******  External Functions    ***************************************/
extern void dmaRead (int bmeNum, UINT32 srcAddr, BYTE *, UINT32);
extern void rdm( int bmeNum, u32 addr, u32 len);
extern void tpr (int BmeNum, unsigned long addr);
extern void tpw (int BmeNum, unsigned long addr, unsigned long data);


/*******  Global Data           ***************************************/
extern BYTE DmaArray[];

/*******  Local Data            ***************************************/
static BYTE * pucBufPtr;
static ipos_port_id rPid;
//static tAPI_REQUEST rApi;
static u8 ucPrintBuf[LOCAL_BUFF_SIZE];

static int iBmeMemPrintAddr[MAX_BME];
static int iBmeMemPrintSize[MAX_BME];
static int iReadPrintBuf[MAX_BME];	// supports 4 BME
static int iDebugDescrp[MAX_BME];
static BYTE cWriteBuf[0x2000];

/*******  Local Functions       ***************************************/
static void bmeMonSkipBlanks( void );
static s16 bmeMonGetChar( void );
static s32 bmeMonGetLong( void );
static void bmeDebugDisplayPrintBuffer (void);
static void bmeMonDisplayMenu (void);

/***********************************************************************
************************************************************************

          L O C A L    F U N C T I O N S

************************************************************************
***********************************************************************/
/*
*****************************************************************************
* Function      : Display Help Menu
* Parameters    : None
* Return        : Nothing
* Description   :
*****************************************************************************
*/
static void bmeMonDisplayMenu (void)
{
	printf ("\n TOP LEVEL BME DEBUG MENU \n\n"
			"cmd input     option description\n"
			"-----------------------------------\n"
			" 0            0|1|2  listBmeMsgQueue (0:brief; 1:list all; 2: list leaked)\n"
			" 1                   listBB\n"
			" 2  port      0|1    xdslLinkDisplayUserPort (0:brief; 1:detail)\n"
			" 3  port      0|1    xdslProtoDisplayUserPort (0:brief; 1:detail)\n"
			" 4                   Version\n"
			" 5                   listBuf\n"
			" 6                   OAMP system DB dump\n"
			" 7  port             OAMP port status\n"
			" 8            0|1    RMC dump\n"
			" 9  port             FMC dump\n"
			" A                   Atm status\n"
			" Bt port             Tx status\n"
			" Br port             Rx status\n"
			" Bn port             BNI bme network fifo status\n"
			" V                   Dump VBUS registers\n"
			" ap afe# reg         AFE reg read (Hex)\n"
			" aw afe# reg val     AFE reg write (Hex)\n"
			" az port             AFE / IFE reg dump\n"
			" b  BME#             Set BME number\n"
			" c                   Clear Event Log\n"
			" e             N     Dump Event Log   N<400\n"
			" rr reg              Register Read (Hex)\n"
			" rw reg val          Register Write val (Hex)\n"
			" dr src N            DMA Read N bytes (Hex) from src (Hex)\n"
			" ph N F C            Print Buffer in Hex: (args same as pd)\n"
			" pd N F C            Print Buffer in Decimal: N bytes (hex)\n"
			"                     F = 0:Nibble, 1:byte, 2:word, 4:long\n"
			"                     C columns\n"
			" fd addr N F O       dump N(Hex) bytes of addr (Hex) to hyper-terminal with\n"
			"                     F (0:Nibble, 1:byte, 2:word, 3:long) size. The output\n"
			"                     format will be based on O (0:Dec, 1:Hex)\n"
			" fl 0|1|2|3|4|5      fill 8k of buffer (0:0x00;1:0xFF;2:0x55;\n"
			"                     3:0xAA; 4:ramp up;5:ramp down\n"
			" h                   HALT XTENSA\n"
			" m  value            use value (Dec) as the new magic number\n"
			" s  item#      0|1|2 set event log trace level (0:warn;1:attn;2:info),\n"
			"                     use cmd l to get item#\n"
			" v                   vxWorks related calls......depends on sub-opcode\n"
			"       I   0         summary of tasks' TCB\n"
                 	"       I   N         complete info on TCB for a Nth task\n"
			"       Q   0         summary of msg queue list\n"
			"       Q   N         complete info on msg queue for Nth queue\n"
//			"       R task_id     resume a task\n"
			" x                   EXIT\n"
			"\n\n i.e. command input option (3 0 1)\n");
}

/*
*****************************************************************************
* Function      : Display Print Buffer (reveived from BME)
* Parameters    : None
* Return        : Nothing
* Description   :
*****************************************************************************
*/
static void bmeDebugDisplayPrintBuffer (void)
{
 s32 wrIdx;
 s32 rdIdx;
 s32 iSize, c;
 UINT8 * pucBuf = ucPrintBuf + 4;

   	wrIdx = * ((s32 *)ucPrintBuf);		//1st 4 bytes contains write index info
	rdIdx = iReadPrintBuf[rPid.bmeNum];
	iSize = iBmeMemPrintSize[rPid.bmeNum];

	if ( wrIdx < rdIdx )
	{
		while ( rdIdx < iSize )
		{
			if ( (c = *(pucBuf + rdIdx)) != 0 )	putchar(c);
			rdIdx++;
		}

		rdIdx = 0;
	}

	while ( rdIdx < wrIdx )
	{
		if ( (c = *(pucBuf + rdIdx)) != 0 )	putchar(c);
		rdIdx++;
	}

//	iReadPrintBuf[rPid.bmeNum] = rdIdx;
	iReadPrintBuf[rPid.bmeNum] = 0;

}


/*
*****************************************************************************
* Function      : Skip Space
* Parameters    : None
* Return        : Nothing
* Description   :
*****************************************************************************
*/
static void bmeMonSkipBlanks( void )
{
	while( *pucBufPtr == ' ' ) { pucBufPtr++ ; }
}


/*
*****************************************************************************
* Function      : Skip Pre-Hex (0x or 0X)
* Parameters    : None
* Return        : Nothing
* Description   :
*****************************************************************************
*/
static void bmeMonSkipPreHex( void )
{
	while( (*pucBufPtr == '0') || (*pucBufPtr == 'x')  || (*pucBufPtr == 'X') )
    {
		pucBufPtr++;
	}
}




/*
*****************************************************************************
* Function      : Convert Hex to Int
* Parameters    : None
* Return        : s16
* Description   :
*****************************************************************************
*/
s16 hex_to_int( u8 c )
{
 s16 value;

	if( ('0' <= c) && (c <= '9') )
	{
		value = c - '0';
	}
	else if( ('A' <= c) && (c <= 'F') )
	{
		value = c - 'A' + 10;
	}
	else if( ('a' <= c) && (c <= 'f') )
	{
		value = c - 'a' + 10;
	}
	else
	{
		value = -1;
	}

	return (value);
}


/*
*****************************************************************************
* Function      : Get user request in Hex format
* Parameters    : None
* Return        : u32
* Description   :
*****************************************************************************
*/
u32 bmeMonGetHex( void )
{
 s32 result = 0;
 s16 c;

	bmeMonSkipBlanks();
	bmeMonSkipPreHex();

	while( (c=hex_to_int( *pucBufPtr )) >= 0 )
	{
		result = ( result << 4 ) + c;
		pucBufPtr++;
	}

	return result ;
}

/*
*****************************************************************************
* Function      : Get user request in char format
* Parameters    : None
* Return        : s16
* Description   :
*****************************************************************************
*/
static s16 bmeMonGetChar( void )
{
 s16 c = 0;

	if ( (c = *pucBufPtr) != 0 )
	{
		pucBufPtr++;
	}

	return(c);
}

/*
*****************************************************************************
* Function      : Get User Request in Long format
* Parameters    : None
* Return        : s32
* Description   :
*****************************************************************************
*/
static s32 bmeMonGetLong( void )
{
 char cNeg = 0 ;
 s32 lResult = 0;
 int c;

	bmeMonSkipBlanks();

	if( *pucBufPtr == '-' )
	{
		cNeg = TRUE;
		pucBufPtr++;
	}

	while( (c=*pucBufPtr) >= '0' && ( c <= '9' ) )
	{
		lResult = (lResult * 10L) + (c - '0');
		pucBufPtr++;
	}

	if( cNeg )
	{
		lResult = -lResult;
	}

	return (lResult) ;
}

/*
*****************************************************************************
* Function      : Fill Local Buffer
* Parameters    : int
* Return        : void
* Description   :
*****************************************************************************
*/
static void bmeMonFillLocalBuff (int iPat)
{
 int i, j;

	switch ( iPat )
	{
		case '0':
			for ( i=0 ; i<LOCAL_WDM_BUFF_SIZE ; i++ )	cWriteBuf[i] = 0;
			break;
		case '1':
			for ( i=0 ; i<LOCAL_WDM_BUFF_SIZE ; i++ )	cWriteBuf[i] = 0xFF;
			break;
		case '2':
			for ( i=0 ; i<LOCAL_WDM_BUFF_SIZE ; i++ )	cWriteBuf[i] = 0x55;
			break;
		case '3':
			for ( i=0 ; i<LOCAL_WDM_BUFF_SIZE ; i++ )	cWriteBuf[i] = 0xAA;
			break;
		case '4':
			for ( i=0 ; i<LOCAL_WDM_BUFF_SIZE ; i++ )	cWriteBuf[i] = (i & 0xFF);
			break;
		case '5':
			for ( j=0,i=LOCAL_WDM_BUFF_SIZE-1 ; i>=0 ; i-- )	cWriteBuf[j++] = (i & 0xFF);
			break;
		default:
			bmeMonDisplayMenu ();
			break;
	}
}


/*
*****************************************************************************
* Function      : Dump Buffer
* Parameters    : BYTE *, int, int, int
* Return        :
* Description   :
*****************************************************************************
*/
static void bmeMonDumpBuffDec (BYTE * addr, int size, int width, int col)
{
 int i;
 s16 * psBuf1;
 u32 * psBuf2;

 if(col <1 || col > 16)
	 col = 1;


	switch ( width )
	{
		case 0:	// nibble
			for ( i=0 ; i<size ; i++ )         {
 				if( (i % col) == 0)
					printf("\n");
				printf ("%01d    %01d    ", (addr[i]&0xF0)>>4, addr[i]&0x0F);
			}
			break;

		case 1:
			for ( i=0 ; i<size ; i++ )         {
 				if( (i % col) == 0)
					printf("\n");
				printf ("%03d    ", addr[i]);
			}
			break;

		case 2:
			psBuf1 = (s16 *) addr;
			for ( i=0 ; i<size/2 ; i++)         {
 				if( (i % col) == 0)
					printf("\n");
				printf("%6d    ", psBuf1[i]);
			}
			break;

		case 3:
		case 4:
			psBuf2 = (u32 *) DmaArray;
			for ( i=0 ; i<size/4 ; i++) {
 				if( (i % col) == 0)
					printf("\n");
				printf("%10d  ", (int) psBuf2[i]);
			}
			break;

		default:
			bmeMonDisplayMenu ();
			break;
	}

}
static void bmeMonDumpBuffHex (BYTE * addr, int size, int width, int col)
{
 int i;
 u32 * psBuf2;
 u16 * pBuf1;

	if(col <1 || col > 16)
		col = 1;

	switch ( width )
	{
		case 0:	// nibble
			for ( i=0 ; i<size ; i++ ) {
				if( (i % col) == 0)
					printf("\n");
				printf ("%01x    %01x    ", (addr[i]&0xF0)>>4, (addr[i]&0x0F));
			}
			break;

		case 1:
			for ( i=0 ; i<size ; i++ ) {
 				if( (i % col) == 0)
					printf("\n");
				printf ("%02x    ", addr[i]);
			}
			break;

		case 2:
			pBuf1 = (u16 *) addr;
			for ( i=0 ; i<size/2 ; i++)         {
				if( (i % col) == 0)
					printf("\n");
				printf("%4x    ", pBuf1[i]);
			}
			break;

		case 3:
		case 4:
			psBuf2 = (u32 *) DmaArray;
			for ( i=0 ; i<size/4 ; i++) {
				if( (i % col) == 0)
					printf("\n");
				printf("%8x  ",(int) psBuf2[i]);
			}
			break;

		default:
			bmeMonDisplayMenu ();
			break;
	}

}

/*
*****************************************************************************
* Function      : Get user request and xmt it to BME
* Parameters    : None
* Return        : TRUE/FALSE
* Description   :
*****************************************************************************
*/
extern void iPosPrintVer(int bmeNum);

int bmeDebugXmtReq (void)
{
 BYTE ucUsrReq [40];
 s32 iParam1, iParam2, iParam3;
 s16 sIn;
 int iStatus = 1;
 int iRepeat = 1;

   	while ( iRepeat )
	{

		iRepeat = 0;
		printf("\nEnter opcode for (BME:%d) or ? for help: ", rPid.bmeNum);
		gets (ucUsrReq);

		pucBufPtr = ucUsrReq;

		BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = 0;
		BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = 0;
		BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = 0;
		BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm4 = 0;
		BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm5 = 0;

		bmeMonSkipBlanks ();
		sIn = bmeMonGetChar();

		switch ( sIn )
		{
			case '2':	/* display xdsl link descriptor */
			case '3':	/* display xdsl proto descriptor */
				bmeMonSkipBlanks ();
				iParam1 = bmeMonGetChar();
				bmeMonSkipBlanks ();
				iParam2 = bmeMonGetChar();

				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');		// opcode
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = (s32)(iParam1 - '0');	// port #
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = (s32)(iParam2 - '0');	// display option
       	 		iposBmeMon(rPid, 10, 0, NULL);
				iStatus = 3;
				break;

			case '0':   /* list BME message queues */
			case '7':	/* dump oamp port status */
			case '8':	/* rx cpu dump */
			case '9':	/* dump fmc circular control message buffer */
				bmeMonSkipBlanks ();
				iParam1 = bmeMonGetChar();

				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1 - '0';
        		iposBmeMon(rPid, 10, 0, NULL);
				break;


			case 'B':
				sIn = bmeMonGetChar ();	//sub-command
				iParam1 = bmeMonGetLong ();	// get port #
				if ( (sIn == 'r') || (sIn == 't') || (sIn == 'n') )
				{
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
				}
				else
				{
					bmeMonDisplayMenu ();
					iStatus = 0;
				}

				if ( iStatus == 1 )
          		iposBmeMon(rPid, 10, 0, NULL);
				break;

			case 'a':
				/* read or write from/to AFE */
				sIn = bmeMonGetChar ();	//sub-command
   				if ( sIn == 'p' )
				{
					iParam1 = bmeMonGetLong ();	// afe #
					iParam2 = bmeMonGetHex ();	// afe reg
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = iParam2;
					iStatus = 4;
				}
				else if ( sIn == 'w' )
				{
					iParam1 = bmeMonGetLong ();
					iParam2 = bmeMonGetHex ();
					iParam3 = bmeMonGetHex ();
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = iParam2;
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm4 = iParam3;
					iStatus = 4;
				}
				else if ( sIn == 'z' )
				{
					iParam1 = bmeMonGetLong ();
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
					BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
					iStatus = 14;
				}
				else
				{
					bmeMonDisplayMenu ();
					iStatus = 0;
				}

				if ( iStatus )
				{
					iposBmeMon(rPid, 10, 0, NULL);
				}
				break;

			case 'b':
				/* set BME number, default to BME=1 */
				iParam1 = bmeMonGetLong ();
				if ( (iParam1 > 0) && (iParam1 <= MAX_BME) )
				{
					rPid.bmeNum = iParam1;
				}
				else
				{
					printf("\n incorrect BME num %d", (int) iParam1);
				}
				iStatus = 0;
				break;

			case 'd':	/* dma from bme */
				iParam1 = bmeMonGetChar ();	//sub-command
				iParam2 = bmeMonGetHex ();  //dma src
				iParam3 = bmeMonGetHex ();	// size
				if ( (iParam3 > 0) && (iParam3 <= 0x2000) )
				{
					if ( iParam1 == 'r' )
					{
					   rdm(rPid.bmeNum, iParam2, iParam3);
					}
					else if ( iParam1 == 'w' )
					{
						printf("\nNot implemented yet...\n");
					}
					else
					{
						bmeMonDisplayMenu ();
					}
				}
				else
				{
					bmeMonDisplayMenu ();
				}

				iStatus = 0;
				break;

			case '1':   /* list BB */
			case '4':   /* BME version */
			case '5':   /* ListBuffs */
			case '6':	/* dump sys DB */
			case 'A':	/* check atm lock status */
			case 'c':	/* clear bme event-log */
			case 'h':	/* halt xtensa, control crash */
			case 'l':	/* dump event manager list */
			case 'V':
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
        		iposBmeMon(rPid, 10, 0, NULL);
				break;

            case 'e':
                iPosPrintVer(rPid.bmeNum);
				iParam1 = bmeMonGetLong ();
				if ( !iParam1 ) iParam1 = 100;
				if ( iParam1 > 2000 ) iParam1 = 2000;
#if 0
				if(!getdump(rPid.bmeNum))
				{
					dump( iParam1);
				}
				else
				{
					printf("\n error accessing bme event-log\n");
				}
#else
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
        		iposBmeMon(rPid, 10, 0, NULL);
#endif
				iStatus = 6;
				break;

			case 'f':
				iParam1 = bmeMonGetChar ();	//sub-command
				if ( iParam1 == 'l' )
				{
					/* fill the local buffer per user request */
					bmeMonSkipBlanks ();
					iParam2 = bmeMonGetChar ();

					bmeMonFillLocalBuff (iParam2);
				}
				else
				{
					bmeMonDisplayMenu ();
				}

				iStatus = 0;
				break;

			case 'm':
				iParam1 = bmeMonGetLong ();
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
        		iposBmeMon(rPid, 10, 0, NULL);
				break;

			case 'p':
				iParam1 = bmeMonGetChar();
				if ( iParam1 == 'h') {
					iParam1 = bmeMonGetHex ();	// get the size
          			iParam2 = bmeMonGetLong (); // get variable size
					iParam3 = bmeMonGetLong ();	// get num of columns

					bmeMonDumpBuffHex (DmaArray, iParam1, iParam2, iParam3);
				}
				else if ( iParam1 == 'd') {
					iParam1 = bmeMonGetHex ();	// get the size
          			iParam2 = bmeMonGetLong (); // get variable size
					iParam3 = bmeMonGetLong ();	// get num of columns

					bmeMonDumpBuffDec (DmaArray, iParam1, iParam2, iParam3);
				}
				else{
					printf("Wrong format");
				}
				iStatus = 0;
				break;

			case 'r':
				sIn = bmeMonGetChar ();	//sub-command
				if ( sIn == 'r' )
				{
					iParam1 = bmeMonGetHex ();
					tpr (rPid.bmeNum, iParam1);
				}

				else if ( sIn == 'w' )
				{
					iParam1 = bmeMonGetHex ();
					iParam2 = bmeMonGetHex ();
					tpw (rPid.bmeNum, iParam1, iParam2);
				}
				else
				{
					bmeMonDisplayMenu ();
				}

				iStatus = 0;
				break;

			case 's':	/* set event-log trace level */
				iParam1 = bmeMonGetLong();
				iParam2 = bmeMonGetLong();

				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');		// opcode
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
				BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = iParam2;
       		 	iposBmeMon(rPid, 10, 0, NULL);
				break;

			case 'v':
			   /* vxWorks system related calls */
				bmeMonSkipBlanks ();
				iParam1 = bmeMonGetChar();
				iParam2 = bmeMonGetLong();
				iParam3 = bmeMonGetLong ();
 				switch ( iParam1 )
				{
					case 'I':
					case 'Q':						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(iParam1 - '0');
						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam2;
						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = iParam3;
      		 				iposBmeMon(rPid, 10, 0, NULL);
						break;

#if 0
					case 'C':
					case 'R':
					case 'S':
					case 'T':
						iParam2 = bmeMonGetHex ();
						Bme[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(iParam1 - '0');	// vxworks func
						Bme[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam2;				// task id
						if (rPid.bmeNum==1) SendMail(API_REQUEST,rPid,UiTask,eBme1DnldTask,sizeof(tAPI_REQUEST),(BYTE*)&rApi);
						if (rPid.bmeNum==2) SendMail(API_REQUEST,rPid,UiTask,eBme2DnldTask,sizeof(tAPI_REQUEST),(BYTE*)&rApi);
						break;
#endif

					default:
						iStatus = 0;
						break;
				}
				break;

			case '?':
				bmeMonDisplayMenu ();
				iRepeat = 1;
				break;

			case 'x':
				iStatus = 0;
				break;
#if 1
			case 't':
				sIn = bmeMonGetChar ();				//sub-command
				if ( sIn == 'b') {						// setup a band(s) to transmit
						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
						iStatus = 4;
				} else if(sIn == 'T') {
						iParam1 = bmeMonGetLong();	// bandplan
						iParam2 = bmeMonGetLong ();	// tone index
						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam1;
						BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = iParam2;
						iStatus = 4;
				}

				if ( iStatus )
				{
					iposBmeMon(rPid, 10, 0, NULL);
				}

				break;
#endif
			default:
				bmeMonDisplayMenu ();
				iStatus = 0;
				break;
		}
	}

	return (iStatus);
}

/***********************************************************************
************************************************************************

          F U N C T I O N     I N T E R F A C E S

************************************************************************
***********************************************************************/
/*
************************************************************************
	Function: Bme Debug Handler

	Description:

	Return Value:
************************************************************************
*/
void bmeDebugHandler (void)
{
 int iStatus ;
 ipos_api_bme	*pApiBme;

	if ( iDebugDescrp[rPid.bmeNum - 1] == 0 )
	{
		pApiBme=(ipos_api_bme *) iposGetBmeHandle(rPid.bmeNum);
    if(iposSemTake(pApiBme->semBme, IPOS_WAIT_FOREVER) == OS_SUCCESS)
    {
		  /* need to get the start address and bme print mem size */
		  bmePioRead (&BmeStruct[rPid.bmeNum], 0x40008320,
                  (U32 *)(U8 *)(&iBmeMemPrintAddr[rPid.bmeNum - 1]));
		  bmePioRead (&BmeStruct[rPid.bmeNum], 0x40008324,
                  (U32 *)(U8 *)(&iBmeMemPrintSize[rPid.bmeNum - 1]));
      iposSemGive(pApiBme->semBme);			/* read BME successful, release the bme Lock */
      if ( iBmeMemPrintSize[rPid.bmeNum - 1] > LOCAL_BUFF_SIZE )
      {
        printf("**** Needed more than 0x%x space (0x%x) for BME %d ***\n",
             LOCAL_BUFF_SIZE, iBmeMemPrintSize[rPid.bmeNum - 1], rPid.bmeNum);
		  }
      iDebugDescrp[rPid.bmeNum - 1] = 1;
    }
    else
      printf("\nCan not get BME mem address and size");
	}

	if ( iDebugDescrp[rPid.bmeNum - 1] == 1 )
	{
    /* get & send user request to BME pointed by rPid.BmeNum */
    if ( (iStatus = bmeDebugXmtReq ()) )
    {
      /* allow other side to process the xmtted request */
      iposTaskDelay(iStatus*50);

      /* dma the print buffer from BME */
      memset ((char *)ucPrintBuf, 0, LOCAL_BUFF_SIZE);
        dmaRead (rPid.bmeNum,
             iBmeMemPrintAddr[rPid.bmeNum - 1],
           ucPrintBuf,
           LOCAL_BUFF_SIZE);

      /* display the print buffer */
      bmeDebugDisplayPrintBuffer ();
    }
  }
}




/*
************************************************************************
	Function: Bme Debug Init

	Description:

	Return Value:
************************************************************************
*/
void bmeDebugInit (void)
{
 int i;

//	rApi.Command = DEBUG_MON;

	rPid.bmeNum  = 1;
	rPid.portNum = 0;

	for ( i=0 ; i<MAX_BME ; i++ )
	{
		iBmeMemPrintAddr [i] = 0;
		iBmeMemPrintSize [i] = 0;
		iReadPrintBuf [i] = 0;

		iDebugDescrp [i] = 0;
	}
}


void reInitBme (void)
{
 ipos_api_bme	*pApiBme;

	/* hold bme in reset mode and reset api and HEC intf */
	bmeRelCpu (&BmeStruct[rPid.bmeNum],FALSE); /* hold BME cpu */

	bmeHwResetApi(rPid.bmeNum);
	iposTaskDelay(10);

	pApiBme=(ipos_api_bme *) iposGetBmeHandle(rPid.bmeNum);
	iposSemGive(pApiBme->semBme);

#ifdef P2CO
	setclk(&BmeStruct[rPid.bmeNum],157);
#else
	setclk(&BmeStruct[rPid.bmeNum],148);
#endif


#ifndef	CPE_30
	InitDmaChannel15 (&BmeStruct[rPid.bmeNum]);
#endif

	InitEMIConfig (&BmeStruct[rPid.bmeNum]);

}

