/**************************************************************
$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.2 $
$Date: 2006/12/12 10:53:07 $
***************************************************************/

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef USE_VXWORKS /* IXDP425 */
#include <v2pthread.h>
#endif
#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);
extern void bmeRelCpu (tBmeStruct *pBme,unsigned char enable);
extern void bmeHwResetApi (int BmeNum);
extern void setclk (tBmeStruct *pBme, int num);
extern	HWAPI_RET_VAL InitEMIConfig (tBmeStruct *bmeStruct);
extern void convertDataToEndianFormat (BYTE bDataSize, BYTE *bDataPtr);

#ifdef ALASKA
extern int readFromVdsl(char *buffer);
extern int writeToVdsl(char *buffer);
#define REMOVE
#endif

/*******  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  port             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 C O     dump N(Hex) bytes of addr(Hex) to hyper-terminal with\n"
			"                     F =0:Nibble, 1:byte, 2:word, 4:long\n"
			"                     C = column   O = 0: Decimal, 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"
            " o  port               OHM related Q and message descriptor details \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
	convertDataToEndianFormat(sizeof(s32), (BYTE *)&wrIdx); // Endian Fix. Beyhan Kerim

	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];
#ifdef ALASKA
 BYTE writeMsg [40];
#endif
 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);
#ifdef ALASKA
    sprintf(writeMsg, "CONTINUE");
    printf("\n                                                \n");
    if(writeToVdsl((char *)&writeMsg) == -1)
    {
	iStatus = 0;
        break;
    }
      printf("\n                                                \n");
      if( readFromVdsl((char *)&ucUsrReq) == -1)
      {
	iStatus = 0;
        break;
      }
#else
		gets (ucUsrReq);
#endif		
#ifdef REMOVE
printf("\n bmeDebugXmtReq ::: string read: %s\n", ucUsrReq);
#endif		
		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 */
			case 'V':
				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 'D':   /* dma DMA access blocks within the bme */
                iParam1 = bmeMonGetChar (); //sub-command
                iParam2 = bmeMonGetHex ();  //dma src 
                iParam3 = bmeMonGetHex ();  // size
                iStatus = 0;
                if ( (iParam3 > 0) && (iParam3 <= 0x4000) )
                {
                     if ( iParam1 == 'r' )
                     {
                         BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm1 = (s32)(sIn - '0');
                         BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm2 = iParam2;
                         BmeStruct[rPid.bmeNum].BmeParms.DebugParms.Parm3 = iParam3;
                         iStatus = 4;
                     }
                     else if ( iParam1 == 'w' )
                     {
                          printf("\nNot implemented yet...\n");
                     }
                     else
                     {
                          bmeMonDisplayMenu ();
                     }
                }
                else
                {
                     bmeMonDisplayMenu ();
                }

                if ( iStatus )
                {
                     iposBmeMon(rPid, 10, 0, NULL);
                }
                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 */
				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 == 'd' )
				{
				 s32 iParam4, iFormat;

					iParam1 = bmeMonGetHex ();		// get starting addr
        			iParam2 = bmeMonGetHex (); 	// get size
					iParam3 = bmeMonGetLong ();	// get var size
					iParam4 = bmeMonGetLong ();	// get num of columns
					iFormat = bmeMonGetLong ();	// get format

					if ( iFormat == 0 )
					{
						bmeMonDumpBuffDec ((BYTE*) iParam1, iParam2, iParam3, iParam4);
					}
					else
					{
						bmeMonDumpBuffHex ((BYTE*) iParam1, iParam2, iParam3, iParam4);
					}
				}
				else 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 'o':
                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 '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;
		}
	}
#ifdef ALASKA
    sprintf(writeMsg, "END");
    writeToVdsl((char *)&writeMsg);
#endif
	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 (pApiBme == NULL) 
		  {
		    printf("\n NULL BME handle, rPid.bmeNum=%d\n", rPid.bmeNum);
		    return;
		  }
    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,
                  (BYTE *)&iBmeMemPrintAddr[rPid.bmeNum - 1]);
		  bmePioRead (&BmeStruct[rPid.bmeNum], 0x40008324,
                  (BYTE *)&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 */
#ifdef REMOVE
printf("\n bmeDebugHandler :: before bmeDebugXmtReq");
#endif
//    iStatus = bmeDebugXmtReq ();
    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 ();
    }
	printf("\n\n");
	sleep(1);
  }
}




/*
************************************************************************
	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);

#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]);	

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

/****
Input: 
	fileName:	output file name i.e. "output"
	Len:		length of data to be saved (0x2000)
	Format:	0: 	decimal   and 1: Hex
	iSz:		1: 1 = byte (defalt),  2 = word,  4 = long
	iCol:		number of col 
****/
int rxCap (char * pcFileName, int iLen, int iFormat, int iSz, int iCol)
{
 FILE *fp = NULL;
 int i, iStatus = 1, k = 0;
 char fileOut[200];
 U32 *pulData;
 S16 *psData;
 U8 *pucData;

	fileOut [0] = '\0';
	iCol--;

	sprintf(fileOut, "/tgtsvr/");
	strcat (fileOut, pcFileName);

	if ((fp = fopen(fileOut, "w+")) == NULL)
	{
		printf("\nUnable to open file %s", fileOut);
		iStatus = -1;
	}
	else
	{
		switch (iSz)
		{
			case 4:
				pulData = (U32 *) DmaArray;
				for(i=0 ; i<iLen/4 ; i++)
				{
					if ( iFormat == 0 )
						fprintf(fp, "%10d ", (int) pulData [i]);
					else
						fprintf(fp, "0x%8x ", (int) pulData [i]);

					if ( ++k > iCol )
					{
						fprintf(fp, "\n");
						k = 0;
					}
				}
				break;

			case 2:
				psData = (S16 *) DmaArray;
				for(i=0 ; i<iLen/2 ; i++)
				{
					if ( iFormat == 0 )
						fprintf(fp, "%6d ", (int) psData [i]);
					else
						fprintf(fp, "0x%4x ", (int) psData [i]);

					if ( ++k > iCol )
					{
						fprintf(fp, "\n");
						k = 0;
					}
				}
				break;
			default:
				pucData = (U8 *) DmaArray;
				for(i=0 ; i<iLen ; i++)
				{
					if ( iFormat == 0 )
						fprintf(fp, "%6d ", (int) pucData [i]);
					else
						fprintf(fp, "0x%4x ", (int) pucData [i]);

					if ( ++k > iCol )
					{
						fprintf(fp, "\n");
						k = 0;
					}
				}
				break;
		}

		if ( fp )
			fclose (fp);
	}

	return (iStatus);
}
