debug.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 573 行

C
573
字号

/*****************************************************************************
 *
 * File:    debug.c
 * Author:  Naresh Gupta (nkgupta@hotmail.com)
 * Purpose: Debug serial port routines for SCI and SCIF.
 *   Copyright (c) 1999 Hitachi,Ltd.
 *
 ****************************************************************************/

#include <windows.h>
#include <ethdbg.h>
#include <halether.h>
#include "platform.h"
#include "nkintr.h"
#include "drv_glob.h"

#define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
static BOOL DebugEtherPresent;

#define SCI 				1
#define SCIF 				2

#define MHz 				1000000  // 10 ** 6.

/*
 * FLOW_CONTROL: Define this for the type of Flow control you want to use
 *               on SCIF
 *
 *  0 No Flow Control
 *  1 Hardware Flow Control
 *  2 Software Flow Control
 */

#define FLOW_NONE				0
#define FLOW_HW					1
#define FLOW_SW					2

/****************************************************************************
 * User Modifiable parametes.
 ****************************************************************************/

/* 
 * 1. What is the BAUD_RATE ?
 *
 * 2. which serial port you want the output to go to ?
 *      Options are :-
 *        SCI		   : Output would go to SCI
 *        SCIF		   : Output would go to SCIF
 *        (SCI | SCIF) : For output to go to both. Input would be from SCI
 *
 * 3. SystemClockFreq
 */
#if (SH_PLATFORM == PLATFORM_ASPEN)
#	define BAUD_RATE			57600 // 57600 // 38400	// 115200
#	define DEBUG_SERIAL_PORT	(SCIF)	
#	define SystemClockFreq 		(33 * MHz) // (16.5 * MHz)	 // 33 MHz.

#elif (SH_PLATFORM == PLATFORM_BIGSUR) 

#	define BAUD_RATE			57600 // 57600 // 38400	// 115200
#	define DEBUG_SERIAL_PORT	(SCIF)	
#	define SystemClockFreq 		(41 * MHz)	 // 33 MHz.

/* Additon -- Maneesh Gupta
 * To access SW1 Register
 */
#define BIGSUR_SW1_VAL    			*(UCHAR volatile *)(BIGSUR_SW1) 
/* End of Additon
 */ 
#else
#	define BAUD_RATE			38400 // 38400	// 115200
#	define DEBUG_SERIAL_PORT	(SCI)	
#	define SystemClockFreq 		(33 * MHz)	 // 33 MHz.

#endif



#define FLOW_CONTROL 			0

/* 
 * USE_EDBG_SERVICES: 
 *    Define this if you want to boot Wince with Debug Ethernet support
 */
// #define USE_EDBG_SERVICES 		1

/****************************************************************************
 * End of User Modifiable parametes.
 ****************************************************************************/

/* Stuff related to Debug Ethernet */
#ifdef USE_EDBG_SERVICES
#define pDriverGlobals  ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
static BOOL DebugEtherPresent;
#endif USE_EDBG_SERVICES



// Registers related to SCI
#define SCSMR    			*(UCHAR volatile *)(0xFFE00000)  
#define SCBRR    			*(UCHAR volatile *)(0xFFE00004)
#define SCSCR    			*(UCHAR volatile *)(0xFFE00008)
#define SCTDR    			*(UCHAR volatile *)(0xFFE0000C)
#define SCSSR    			*(UCHAR volatile *)(0xFFE00010)
#define SCRDR    			*(UCHAR volatile *)(0xFFE00014)
#define SCSCMR   			*(UCHAR volatile *)(0xFFE00018)
#define SCSPTR   			*(UCHAR volatile *)(0xFFE0001C)

// Bit fields of Serial Status Register.
#define SCI_TDRE				0x80
#define SCI_RDRF 				0x40
#define SCI_ORER  				0x20
#define SCI_FER 				0x10
#define SCI_PER  				0x08
#define SCI_TEND  				0x04
#define SCI_MPB  				0x02
#define SCI_MPBT  				0x01


// Registers related to SCIF
#define SCSMR2    			*(USHORT volatile *)(0xFFE80000)
#define SCBRR2    			*(UCHAR  volatile *)(0xFFE80004)
#define SCSCR2    			*(USHORT volatile *)(0xFFE80008)
#define SCFTDR2   			*(UCHAR  volatile *)(0xFFE8000C)
#define SCFSR2    			*(USHORT volatile *)(0xFFE80010)
#define SCFRDR2   			*(UCHAR  volatile *)(0xFFE80014)
#define SCFCR2    			*(USHORT volatile *)(0xFFE80018)
#define SCFDR2    			*(USHORT volatile *)(0xFFE8001C)
#define SCSPTR2   			*(USHORT volatile *)(0xFFE80020)
#define SCLSR2    			*(USHORT volatile *)(0xFFE80024)

// Bit fields for Serial Status Register on SCIF
#define SCIF_ER				0x80
#define SCIF_TEND			0x40
#define SCIF_TDFE			0x20
#define SCIF_BRK			0x10
#define SCIF_FER			0x08
#define SCIF_PER			0x04
#define SCIF_RDF			0x02
#define SCIF_DR				0x01
#define SCIF_ORER			0x01		// in SCLSR2

/* Baud rate setting is calculated according to the following formula :-
 *  N = P * 10**6 / (64 * 2 ** (2n - 1) * B)  -1 
 */
#define cks					0.5		 // 2**(2n-1) value for clock source P.

#define ceil(x)  ((x > (float)(int)x) ? ((int)x + 1) : ((int) x))
#define brr(bps) ceil(((float)SystemClockFreq/(64 * cks * bps)) -1)

// I prefer keeping the current baud rate in a variable instead of using this
// formula because this formula may give a slightly different baud rate
// due to the rouding off done earlier.
#define brr2baud(N)  ( ((float)SystemClockFreq)/(64 * cks * (N+1)) )

// Function prototypes.
void OutputFormatString(const unsigned char *sz, ...);
void OEMWriteDebugByte(UCHAR ch);
void HandleError(int port);

// This will keep the CurrentBaudRate.
static int CurrentBaudRate;

#if (SH_PLATFORM == PLATFORM_BIGSUR)
static int DebugSrvType=0; //if 0 Debug Serial else Ethernet Debug
#endif

#if 0
//***********************************************************************
// [ITE] Cash 19971225
//       I don't know why. When initilize SCI port must insert delay
//       routine for SH7750. SH7709 do not need.
//       Maybe check timming!!
//***********************************************************************
void DummyDelay(void)
{    unsigned int i;
     for(i=0;i<0x00001;i++);

}
#endif

/* This routine sets the baud rate to the specified value and returns the
 * new baud rate.
 * If the input is 0, it just returns the current baud rate.
 */
int OEMSetDebugSerialBaudRate(unsigned baud)
{
	if(baud == 0)
		return CurrentBaudRate;

 	if (DEBUG_SERIAL_ON) {
		if(DEBUG_SERIAL_PORT & SCI) {
			// OutputFormatString("New Value of SCBRR = 0x%x, Old Value = 0x%x\n", brr(baud), SCBRR);
			SCBRR = brr(baud);
			CurrentBaudRate = baud;
		}
		if(DEBUG_SERIAL_PORT & SCIF) {
			// OutputFormatString("New Value of SCBRR2 = 0x%x, Old Value = 0x%x\n", brr(baud), SCBRR);
			SCBRR2 = brr(baud);
			CurrentBaudRate = baud;
		}
 	}
	return CurrentBaudRate;
}

/*****************************************************************************
*
*
*   @func   void    |   OEMInitDebugSerial | Initialize debug monitor port.
*
*   NOTE: This function MUST NOT use any global variables!!!!!!
*/
extern void InitDebugEther (void);

void OEMInitDebugSerial(void)
{

//	WRITE_REGISTER_UCHAR(ALPHA_LED, 46);	

 if (DEBUG_SERIAL_ON) {
	if(DEBUG_SERIAL_PORT & SCI) {
		SCSCR = 0x00;
        SCSMR = 0x00;   /* n=0 */

		// NKCH: tried to increase baud rate.
		// BRR for 33 MHz peripheral bus :-
		//	  38400: 0x1A
		//    57600: 0x11
	    //   115200: 0x08: Fastest mode that works.
		//   230400: 0x03

		SCBRR = brr(BAUD_RATE);
		CurrentBaudRate = BAUD_RATE;
		// You need to wait for 1 bit time. To be on the safe side wait for 
		// longer duration
		{ 
			int i = 100000;
		  	while(i--);
		}
        SCSCR = 0x30;   /*   TE,RE enabled */
#if 0
        SCTDR = 0x41;
        SCSSR = 0x80;
        DummyDelay();
        SCRDR = 0x00;
        DummyDelay();
        SCSPTR = 0;
#endif
	}

	if(DEBUG_SERIAL_PORT & SCIF) {
		unsigned current;
		SCSCR2 = 0x0000;
		SCFCR2 = 0x06;	// Reset FIFOs
		SCSCR2 = 0x0000;
		SCSMR2 = 0x0000; // 8N1. n = 0;

		
#if ((SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR))		
		current = SCBRR2;
		if( (current == 8) || (current == 0x11)) {
			/* Hopefull we booted from CMON. No need to change SCBRR2. */
		} else {
			SCBRR2 = brr(BAUD_RATE);
		}
#else ((SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR))		
		SCBRR2 = brr(BAUD_RATE);
#endif ((SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR))		


// #ifdef ASPEN
		// SCBRR2 = 0x8;
// #endif ASPEN

		CurrentBaudRate = BAUD_RATE;
		// You need to wait for 1 bit time. To be on the safe side wait for 
		// longer duration
		{ 
			int i = 100000;
		  	while(i--);
		}
#if (!defined(FLOW_CONTROL) || (FLOW_CONTROL == FLOW_NONE))
		SCFCR2 = 0x00;	
#endif (FLOW_CONTROL == FLOW_NONE)

#if (FLOW_CONTROL == FLOW_HW)
		SCFCR2 = 0x08;	// MCE: Modem control enable. Use CTS, RTS
#endif (FLOW_CONTROL == FLOW_HW)

		SCFSR2 = 0x00;
		// SCFCR2 = 0x00;	// Reset FIFOs
		SCSCR2 |= 0x0030;
	}

    EdbgOutputDebugString("Ethernet Load MagicNum 0x%x from 0x%x\r\n",
			pDriverGlobals->eth.EbootMagicNum,&(pDriverGlobals->eth.EbootMagicNum));
#ifndef BOOT_LOADER
	InitDebugEther();
#endif // BOOT_LOADER

}

//#if (SH_PLATFORM == PLATFORM_BIGSUR)
  // BigSur: Hard code this value for Mode 3.
//  SCBRR2 = 0xE;
//#endif // (SH_PLATFORM == PLATFORM_BIGSUR)

/* Addition -- Maneesh Gupta
 * In Bigsur Switch SW1 specify whether to use Ethernet Debug  or 
 * Serial debug.So we check the switch value and shift to ethernet 
 * debug service if required
 */
/*#if (SH_PLATFORM == PLATFORM_BIGSUR)
 if( (BIGSUR_SW1_VAL & 0x04) != 0) 
	DebugSrvType=1; //Use Ethernet Debug Service

if(DebugSrvType)
{
#endif
*/
/* End of Addition -- Maneesh Gupta
 */

/* Add support for Ethernet Debug Services. */
		
#ifdef USE_EDBG_SERVICES

#ifndef BOOT_LOADER

	InitDebugEther();

#endif // BOOT_LOADER

 
#endif USE_EDBG_SERVICES
/* #if (SH_PLATFORM == PLATFORM_BIGSUR)
}
#endif
*/ 
}


/*****************************************************************************
*
*
*   @func   void    |   OEMWriteDebugString | Display string to the monitor port.
*
*   @parm   unsigned short * | str |
*           Points to the receiving buffer.
*/
void
OEMWriteDebugString(unsigned short *str) {

 if (DEBUG_SERIAL_ON)
   {
    while (*str)
        OEMWriteDebugByte((unsigned char)*str++);
   }
}


/*****************************************************************************
*
*
*   @func   void    |   OEMWriteDebugByte | Output byte to the monitor port.
*
*   @parm   unsigned char *| str |
*           Points to the output buffer.
*/
void
OEMWriteDebugByte(UCHAR ch)
{
	int timeout = 0;

 if (DEBUG_SERIAL_ON) {
	if(DEBUG_SERIAL_PORT & SCI) {
		// Wait for SCI to get ready for transmittal.
		while(!(SCSSR & SCI_TDRE)) { // Wait for TDFE
			if(timeout ++ >= 5000) {
				HandleError(SCI);
				return;
			}
		}
		SCTDR = ch;
		SCSSR &= ~SCI_TDRE;	// Clear TDFE
	}
#if 0
waitTX:
        DummyDelay();
        if((SCSSR & 0x80)==0x80)
        {
           //  *(UCHAR *)(0xa6e00000) = ~0x25;
             SCTDR = ch;
        DummyDelay();
             SCSSR &= 0x7F;
        DummyDelay();
             if((SCSSR & 0x04)==0x04) {
                   	// *(UCHAR *)(0xa6e00000) = ~0x26;
		}
             goto out;
        }
        goto waitTX;
   	}

out:
#endif
	if(DEBUG_SERIAL_PORT & SCIF) {
		while(!(SCFSR2 & SCIF_TDFE)) { // Wait for TDFE
			if(timeout ++ >= 5000) {
				HandleError(SCIF);
				return;
			}
		}
		SCFTDR2 = ch;
		SCFSR2 &= ~SCIF_TDFE;	// Clear TDFE
	}
   }
}

/*****************************************************************************
*
*
*   @func   int    |   OEMReadDebugByte | Get a byte from the monitor port.
*
*   @rdesc  Returns:
*           OEM_DEBUG_COM_ERROR        Error detected
*           OEM_DEBUG_READ_NODATA      No data is available at the port.
*           ch                         If data is available.
*
*/
int
OEMReadDebugByte()
{
#if 0
	UCHAR ch;

 if (DEBUG_SERIAL_ON)
   {

        // *(UCHAR *)(0xa6e00000) = ~0x01;
	if (SCSSR & 0x38)			// See if there is an error
		HandleError();
        DummyDelay();
        // *(UCHAR *)(0xa6e00000) = ~0x03;

        DummyDelay();
        // *(UCHAR *)(0xa6e00000) = ~0x07;
	if( !( SCSSR & 0x40 ) )	// See if RDRF = 1
	{
        	// *(UCHAR *)(0xa6e00000) = ~0x0f;
    		return OEM_DEBUG_READ_NODATA;
	}
	ch = SCRDR;
        DummyDelay();
       	// *(UCHAR *)(0xa6e00000) = ~0x1f;
	SCSSR &= ~0x40;		// Clear RDF
       	// *(UCHAR *)(0xa6e00000) = ~0x3f;
	return ch;
   }
	return (0);
#else

	// Modified by Naresh Gupta.
	// pp 15-33 SH4 hardware reference manual.
	UCHAR ch;
 	if (DEBUG_SERIAL_ON) {
	  if(DEBUG_SERIAL_PORT & SCI) {
		//while(TRUE) 
		{
			ch = (SCSSR & (SCI_ORER | SCI_PER | SCI_FER));
			if(ch) {
				HandleError(SCI);
				return OEM_DEBUG_READ_NODATA;
//				continue;
			}
			if(!(SCSSR & SCI_RDRF))
				return OEM_DEBUG_READ_NODATA;
//			continue;
			ch = SCRDR;
			SCSSR &= ~SCI_RDRF;
			// OutputFormatString("SCRDR=0x%x, ch=0x%x, SCSSR=0x%x\r\n", SCRDR, ch, SCSSR);
			return((int)ch);
		}
	  }

	  if(DEBUG_SERIAL_PORT & SCIF) {
		//while(TRUE) 
		{
			ch = (SCFSR2 & (SCIF_DR | SCIF_ER | SCIF_BRK | SCIF_FER | SCIF_PER));
			ch |= (SCLSR2 & SCIF_ORER);
			if(ch) {
				// OutputFormatString("Error in Serial Receiption. Error Flag = %B\r\n", ch);
				HandleError(SCIF);
				return OEM_DEBUG_READ_NODATA;
//				continue;
			}
			if(!(SCFSR2 & SCIF_RDF))
				return OEM_DEBUG_READ_NODATA;
//				continue;
			ch = SCFRDR2;
			SCFSR2 &= ~SCIF_RDF;
			return((int)ch);
		}
	  }
	}
	return OEM_DEBUG_READ_NODATA;


#endif

}

void HandleError(int port)
{
	// OutputFormatString("+HandleError\r\n");
	if(port == SCI) {
		SCSSR &= ~(SCI_ORER | SCI_FER | SCI_PER);
	}
	if(port == SCIF) {
		SCFSR2 &= ~(SCIF_ER | SCIF_BRK | SCIF_DR | SCIF_PER | SCIF_FER);
		SCLSR2 &= ~SCIF_ORER;
	}
}

/*****************************************************************************
*
*
*   @func   void    |   OEMClearDebugComError | Clear a debug communications error
*
*/
void
OEMClearDebugCommError(void)
{
	// Clears error on all the enabled debug ports.
	// use HandleError if you want to clear only one of the ports.
 	if (DEBUG_SERIAL_ON) {
	  	if(DEBUG_SERIAL_PORT & SCI) 
			HandleError(SCI);
	  	if(DEBUG_SERIAL_PORT & SCIF) 
			HandleError(SCIF);
	}
}

/* This function will Assert the RTS# pin */
OEMStopSerialInput(void)
{
#if (FLOW_CONTROL == FLOW_HW)
	SCFCR2 &= ~0x08;	// Modem control Disable
	SCSPTR2 |= 0x00C0;
#endif (FLOW_CONTROL == FLOW_HW)
	return 0;
}

/* This function will De-assert the RTS# pin */
OEMStartSerialInput(void)
{
#if (FLOW_CONTROL == FLOW_HW)
	SCSPTR2 &= ~0x00C0;
	SCFCR2 |= 0x08;	// Modem control Enable
#endif (FLOW_CONTROL == FLOW_HW)
	return 0;
}

void 
OEMWriteDebugLED(WORD wIndex, DWORD dwPattern)
{
    // Some Odos mirror the LEDS for different ranges than others.
    // Make sure we don't try to write outside that range.
    WRITE_REGISTER_ULONG(LED_ALPHA+((wIndex*sizeof(ULONG)) & LED_ALPHA_MIRROR), 
                             dwPattern);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?