⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parallel.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995, 1996, 1997, 1998  Microsoft Corporation

Module Name:  
    parallel.c

Abstract:  
    This contains parallel bootloader support

Functions:


Notes: 

--*/
#define BOOT_LOADER
#include "..\kernel\hal\mdppfs.c"

#include <pehdr.h>
#include <romldr.h>
#include <halether.h>
#include "p2.h"
#include "p2debug.h"
#include "loader.h"
#include "ethdown.h"

#define DL_SUCCESS			0			// successful download
#define DL_PARALLEL_ERROR	1			// error on parallel port
#define DL_FLASH_ERROR		2			// error on flash
#define DL_CHECKSUM_ERROR	3			// checksum error
#define DL_TIMEOUT			4			// inactivity timeout

//
// Global defines and declarations
//
const unsigned char   BootHeader[] = {
	0xAA,								// header = 4 bytes
	0x55,
	0x55,
	0xAA,
	0x00,								// opcode = 2 bytes (0 = BOOT)
	0x00,
	};
#define BOOT_HEADER_SIZE (sizeof(BootHeader) / sizeof(BootHeader[0]))

const unsigned char   BootTail[] = {
	0x5A,								// trail = 4 bytes
	0xA5,
	0x0A,
	0x1A
	};
#define BOOT_TAIL_SIZE (sizeof(BootTail) / sizeof(BootTail[0]))

const unsigned char   BootPacket[] = {
	0xAA,								// header = 4 bytes
	0x55,
	0x55,
	0xAA,
	0x00,								// opcode = 2 bytes (0 = BOOT)
	0x00,
	0x05,								// length = 2 bytes
	0x00,
	0xFA,								// checksum = 1 byte
	0x5A,								// trail = 4 bytes
	0xA5,
	0x0A,
	0x1A
	};

#define BOOT_PACKET_SIZE (sizeof(BootPacket) / sizeof(BootPacket[0]))

const unsigned char   SyncBytes[] = {
	'0',
	'0',
	'0',
	'F',
	'F'
	};

#define SIZE_OF_SYNC_BYTES  7

extern DWORD dwPhysStart;				// image physical starting address
extern DWORD dwPhysLen;					// image physical length
extern DWORD dwOffset;
extern DWORD dwLaunchAddr;
extern DWORD *dwFlashCache;
extern LPDWORD pdwRecStart, pdwRecNext;		// saved record address, length and checksum pointers

// Flash routines
UINT16 IsFlash( DWORD dwPhysStart, DWORD dwPhysLen );
UINT16 FlashErase(FlashCommands FlashCommand, DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg );
UINT16 FlashWrite( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg );

DWORD OEMEthGetSecs( void );

//***************************************************************************
//	ParallelPortRead - read bytes from parallel port
//
//	Syntax:
//
//    int
//    ParallelPortRead(
//        unsigned char * pByteReceived,
//        unsigned int    cb
//        );
//
//	Arguments:
//
//    pByteReceived (a0)  : points to the buffer to receive data
//    cb            (a1)  : number of bytes to read
//
//Return Value:
//
//    returns the number of bytes left to read (in our case, always 0)
//***************************************************************************
int ParallelPortRead(unsigned char *pByteReceived, unsigned int cb) {
	int result;
	while (cb && (result=OEMParallelPortGetByte()) != -1) {
		*pByteReceived++= (unsigned char)result;
		cb--;
	}
	return cb;
}

/*++

ParallelPortWrite:

    This routine has been optimized for parallel port output.

Syntax:

    int
    ParallelPortWrite(
        unsigned char * pByteReceived,
        unsigned int    cb
        );

Arguments:

    pByteReceived (a0)  : points to the buffer to send
    cb            (a1)  : number of bytes to send

Return Value:

    in v0, the number bytes left to write

--*/
//***************************************************************************
//	ParallelPortWrite
//***************************************************************************
int ParallelPortWrite(const unsigned char *pByteSend, unsigned int cb) {
	while (cb--)
		OEMParallelPortSendByte(*pByteSend++);
	return cb;
}


//***************************************************************************
//	IsParallelReady - is parallel port connected and ready for transfer
//
//  
//***************************************************************************
BOOL IsParallelReady(void) {
										// parallel port status
    DWORD dwStatus = (DWORD)PAR_BUSY_NFAULT | PAR_SELECT;
	DWORD dwStart;

	dwStart= OEMEthGetSecs();
										// set direction to write
    *(PVDWORD)(PAR_CONTROL_REG) = dwStatus;
										// wait for AUTOFD
 	while (!((dwStatus= *(PVDWORD)(PAR_CONTROL_REG)) & PAR_AUTOFD)) {
		if (OEMEthGetSecs()-dwStart > 3)
			return FALSE;
	}
	return TRUE;
}

//***************************************************************************
//	Download2Flash - download image to flash
//
//
//***************************************************************************
unsigned int Download2Flash(void) {
	unsigned int	Vaddr;				// record starting address
	unsigned int	cbRecord;			// record length
	unsigned int	checksum;			// record checksu,
	unsigned int	result;
	char *pszErrorMsg;
										// record header buffer
	unsigned int	ParallelRecvBuffer[3];

 	if (FlashErase( FLASH_START_ERASE, dwPhysStart, dwPhysLen, &pszErrorMsg )) {
		EdbgOutputDebugString("ERROR: FlashErase FLASH_START_ERASE PhysStart %Xh PhysLen %Xh failed\r\n",dwPhysStart,dwPhysLen);
		EdbgOutputDebugString(pszErrorMsg);
		return DL_FLASH_ERROR;
	}

	while (1) {
	 	if (FlashErase( FLASH_CONT_ERASE, dwPhysStart, dwPhysLen, &pszErrorMsg )) {
			EdbgOutputDebugString("ERROR: FlashErase FLASH_CONT_ERASE PhysStart %Xh PhysLen %Xh failed\r\n",dwPhysStart,dwPhysLen);
			EdbgOutputDebugString(pszErrorMsg);
			return DL_FLASH_ERROR;
		}
										// Read in the starting address and length in bytes
		ParallelPortRead((unsigned char *)ParallelRecvBuffer, 3 * sizeof(unsigned int ));
		Vaddr = ParallelRecvBuffer[0];
		cbRecord = ParallelRecvBuffer[1];
		checksum = ParallelRecvBuffer[2];
		*pdwRecNext++= Vaddr;
		*pdwRecNext++= cbRecord;
		*pdwRecNext++= checksum;

		if (!Vaddr && !checksum) {		// if this is the last record, launch it
			if (FlashWrite(dwPhysStart, dwPhysLen, &pszErrorMsg )) {
				EdbgOutputDebugString("ERROR: FlashWrite PhysStart %Xh PhysLen %Xh failed\r\n",dwPhysStart,dwPhysLen);
				EdbgOutputDebugString(pszErrorMsg);
				return DL_FLASH_ERROR;
			}
			cbRecord -= dwOffset;
			break;
		}

		// otherwise copy directly to RAM
		Vaddr-=dwPhysStart;
		Vaddr+=FLASH_CACHE;
		if (cbRecord) {
			result= ParallelPortRead((unsigned char *)Vaddr, cbRecord);
		}
	} // while 1
	dwLaunchAddr=cbRecord;
	return DL_SUCCESS;
}



//***************************************************************************
//	Download2RAM - download image to RAM
//
//
//***************************************************************************
unsigned int Download2RAM(void)
{
	unsigned int	Vaddr;				// record starting address
	unsigned int	cbRecord;			// record length
	unsigned int	checksum;			// record checksu,
	unsigned int	result;
										// record header buffer
	unsigned int	ParallelRecvBuffer[3];

	while (1) {
										// Read in the starting address and length in bytes
		ParallelPortRead((unsigned char *)ParallelRecvBuffer, 3 * sizeof(unsigned int ));
		Vaddr = ParallelRecvBuffer[0];
		cbRecord = ParallelRecvBuffer[1];
		checksum = ParallelRecvBuffer[2];
		*pdwRecNext++= Vaddr;
		*pdwRecNext++= cbRecord;
		*pdwRecNext++= checksum;

		if (!Vaddr && !checksum) { 				// if this is the last record, launch it
			cbRecord -= dwOffset;
			break;
		}

		Vaddr -= dwOffset;

		// otherwise copy directly to RAM
		if (cbRecord) {				
			result= ParallelPortRead((unsigned char *)Vaddr, cbRecord);
										// Read data into destination directly
		}
	} // while 1
	dwLaunchAddr=cbRecord;
	return DL_SUCCESS;
}



/*****************************************************************************
*
*
*   @func   int	|   DownloadImage | Down loads image from host
*
*   @rdesc  Returns 1 if sucessfully downloaded, 0 otherwise
*
*   @parm   const unsigned char * |   pPathName  |
*			   points to a ASCIIZ string for a file on the host file 
*			   system to be downloaded.  The file must be in the format
*			   of SRE or BIN (preprocessed SRE file).
*
*   @parm   unsigned int * |   pStartingAddr	|
*			   points to a buffer to receive the starting address of 
*			   the program.
*
*   @parm   int | fLaunch |
*			   Flag indicating if the downloaded image should be 
*			   automatically launched or not.
*
*   @comm
*		   Initially sends a packet to host (running ppfs) to initiate a 
*		   SRE or binary image  file transfer.
*
*/
int ParallelDownloadImage(void)
{
//    const unsigned char * pTemp;
	unsigned char   ParallelRecvBuffer[512];
	unsigned int	chksum;
	unsigned int	uiTemp;
	int			 bootType;
	unsigned		len;
	unsigned char * pDestByte;
	int			 fSre=0;
	int			 nReturn=0;
	int			 j;
	int			 i;
#ifndef ARM720
	if (!IsParallelReady()) {
		EdbgOutputDebugString("Parallel connection failed.\r\n");
		return 0;
	}	
#endif
	EdbgOutputDebugString("Ready to down load BIN file");

    for (j = 0; j < 100; j++) {
        EdbgOutputDebugString(".");
        //
        // Prepare boot packet
        //
        pDestByte = ParallelRecvBuffer;
        for (i = 0; i < BOOT_HEADER_SIZE; i++) {
            *pDestByte++ = BootHeader[i];
        }
        
        chksum = 0;
        len = sizeof(unsigned int) + 5;
        
        bootType = BOOT_TYPE; 
        
        uiTemp = len;
        for (i = 0; i < 2; i++) {
            *pDestByte++ = (unsigned char)(uiTemp & 0xFF);
            chksum += (uiTemp & 0xFF);
            uiTemp >>= 8;
        }
        
        uiTemp = bootType;
        for (i = 0; i < sizeof(int); i++) {
            *pDestByte++ = (unsigned char)(uiTemp & 0xFF);
            chksum += (uiTemp & 0xFF);
            uiTemp >>= 8;
        }
        
        *pDestByte++ = (unsigned char)((~chksum) & 0xFF);
        
        for (i = 0; i < BOOT_TAIL_SIZE; i++) {
            *pDestByte++ = BootTail[i];
        }

        nReturn=ParallelPortWrite(ParallelRecvBuffer, 
           (unsigned int)(pDestByte - ParallelRecvBuffer));
		//
		// The first six bytes should be "S000FF" (for SRE file) or
		// "B000FF" (for files with internal binary format)
		//
		nReturn=ParallelPortRead(ParallelRecvBuffer, SIZE_OF_SYNC_BYTES);

		if (ParallelRecvBuffer[0] == 'S') {
			fSre = 1;
			break;
		} else if (ParallelRecvBuffer[0] == 'B') {
			fSre = 0;
			break;
		} else { 
			nReturn = - 4;
			continue;
		}
		
		for (i = 1; i < SIZE_OF_SYNC_BYTES; i++) {
			if (ParallelRecvBuffer[i] != SyncBytes[i - 1]) {
				nReturn = - 4;
				goto cont;
			}
		}
		cont:;
	}
	
	//
	//  display any errors returned
	//
	switch (nReturn) {
		case - 1:
		EdbgOutputDebugString("\nCan't set parallel port direction to write\nLaunching existing image...\r\n");
//		LaunchExisting();
		case - 2:
		EdbgOutputDebugString("\nHost computer not responding\n");
		goto doom;
		case - 3:
		EdbgOutputDebugString("\nCan't set parallel port direction to read\n");
		return 0;
		case - 4:
		EdbgOutputDebugString("\nFail to synchonize with the host\n");
		doom:
		EdbgOutputDebugString("Make sure you have ppfs running on the host computer\n");
		EdbgOutputDebugString("and reset the client to restart\r\nLaunching existing image...\r\n");
//		LaunchExisting();
	}

	//
	// Ok, we are synchronized with the host now
	// start streaming the data records
	//
	// if file type is .BIN, read physical start and length
	if (!fSre) 
	{
		// get the next 8 bytes 
		if (ParallelPortRead(ParallelRecvBuffer, 8)==-1) {
			EdbgOutputDebugString("\r\nFailed to read sync bytes.\r\nLaunching existing image...\r\n");
//			LaunchExisting();
		}

		// get physical start and length
		dwPhysStart = *((unsigned int  *)ParallelRecvBuffer);
		dwPhysLen = *(((unsigned int  *)ParallelRecvBuffer) + 1);
		EdbgOutputDebugString("\r\nImage start %Xh length %Xh.  ",dwPhysStart,dwPhysLen);
		
		dwOffset = 0;
#ifdef ARM
		// translate to 8cxxxxxx for arm
		switch (dwPhysStart & 0xff000000) {
		case 0xc7000000:
			// SA1100
			dwOffset = 0x3b000000;
			break;
		case 0x0c000000:		// RAM, ARM720/ARM920
		case 0x0:				// FLASH, any ARM
			dwOffset = 0x80000000;
			break;
		default:
			EdbgOutputDebugString ("Physical Start not translated: 0x%x\r\n", dwPhysStart);
		}
#endif

		// if image is going to flash area
		// it will first be downloaded to RAM
		if (IsFlash(dwPhysStart,dwPhysLen))
		{
			EdbgOutputDebugString("Image going to FLASH.\r\n");
			pdwRecStart=pdwRecNext=(LPDWORD)(FLASH_CACHE+dwPhysLen);
			nReturn= Download2Flash();
		}
		else
		{
			EdbgOutputDebugString("Image going to RAM.\r\n");
			pdwRecStart=pdwRecNext=(LPDWORD)(dwPhysStart+dwPhysLen-dwOffset);
			nReturn= Download2RAM();
		}
		switch (nReturn) {
			case DL_PARALLEL_ERROR:		// error on parallel port
				EdbgOutputDebugString("ERROR: parallel port error. Download aborted.\r\n");
				break;
			case DL_FLASH_ERROR:		// error on flash
				EdbgOutputDebugString("ERROR: flash error.  Download aborted.\r\n");
				break;
			case DL_CHECKSUM_ERROR:		// checksum error
				EdbgOutputDebugString("ERROR: checksum mismatch.  Download aborted.\r\n");
				break;
			case DL_TIMEOUT:			// inactivity timeout
				EdbgOutputDebugString("ERROR: inactivity timeout.  Download aborted.\r\n");
				break;
		}
	}
	return DL_SUCCESS;
}

⌨️ 快捷键说明

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