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

📄 mx21serial.cpp

📁 Redboot, boot-loader of Linux for Freescale ARM family.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <conio.h>
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <stdio.h>
#include <windows.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <io.h>
#include "mx21serial.h"

static int debug = 0;
static int action = ENUM_NULL;
const DATA_LEN = 1024 * 4;
static unsigned char scratch_buf[DATA_LEN]; 		// 16KB data

//                                cmd   |     addr     | width |  count   |    data      | end
unsigned char irom_readl[16]   = {1, 1,  _x, _x, _x, _x,  32,    0, 0, 0, 4,  0, 0, 0, 0,  0};
unsigned char irom_readw[16]   = {1, 1,  _x, _x, _x, _x,  16,    0, 0, 0, 2,  0, 0, 0, 0,  0};
unsigned char irom_readb[16]   = {1, 1,  _x, _x, _x, _x,  8,     0, 0, 0, 1,  0, 0, 0, 0,  0};
unsigned char irom_writel[16]  = {2, 2,  _x, _x, _x, _x,  32,    0, 0, 0, 4,  _x,_x,_x,_x, 0};
unsigned char irom_writew[16]  = {2, 2,  _x, _x, _x, _x,  16,    0, 0, 0, 2,  _x,_x,_x,_x, 0};
unsigned char irom_writeb[16]  = {2, 2,  _x, _x, _x, _x,  8,     0, 0, 0, 1,  _x,_x,_x,_x, 0};
unsigned char irom_status[16]  = {5, 5,  0,  0,  0,  0,   0,     0, 0, 0, 0,  0, 0, 0, 0,  0};
unsigned char irom_download[16]= {4, 4,  _x, _x, _x, _x,  0,    _x,_x,_x,_x,  0, 0, 0, 0,  END_RPT};
unsigned char irom_exec[16]    = {4, 4,  _x, _x, _x, _x,  0,     0, 0, 0, 0,  0, 0, 0, 0,  END_EXEC};
							//	  0	 1	  2	  3	 4	 5	  6		 7	8  9  10  11 12	13 14  15

struct reg_addr_val {
	unsigned long r_w;
	unsigned long addr;
	unsigned long val;
} mx21reg_initsys[] = {
	// ### AHB-Lite IP Interface
	{REG_WEITE, 0x10000000, 0x00040304},
	{REG_WEITE, 0x10020000, 0x00000000},
	{REG_WEITE, 0x10000004, 0xFFFBFCFB},
	{REG_WEITE, 0x10020004, 0xFFFFFFFF},
	{REG_WEITE, 0x10027020, 0x31084003},
	// # CS0 Initialization (Async Mode) 32-bit, ?? wait states              
	{REG_WEITE, 0xDF001000, 0x00000E01},
	{REG_WEITE, 0xDF001004, 0x00000E01},
	// # Setting for Memory Map IO Port
	// # CS1 Initialization (Async Mode)
	// # 16-bit, D0..15, ?? wait states
	{REG_WEITE, 0xDF001008, 0x00002000},
	{REG_WEITE, 0xDF00100C, 0x11118501},
	// # CSD0 Initialization (SDRAM)   
	{REG_WEITE, 0xDF000000, 0x92120300},
	// *** Issue Precharge all Command
	{REG_READ,  0xC0200000, 0},          
	// *** Set AutoRefresh Command
	{REG_WEITE, 0xDF000000, 0xA2120300},
	// *** Issue AutoRefresh Command
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	{REG_READ,  0xC0000000, 0},
	// *** Set Mode Register
	{REG_WEITE, 0xDF000000, 0xB2120300},
	{REG_READ,  0xC0119800, 0},
	{REG_WEITE, 0xDF000000, 0x8212F339},
	// ### End of Memory Configuration
	{REG_WEITE, 0x1003F300, 0x00123056},
	// ### CSCR: FCLK=MPLL/1; HCLK=FCLK/4; #####(If MPLL==266MHz, FCLK=266MHz and HCLK=66MHz)
	{REG_WEITE, 0x10027000, 0x17000E07},
	// for flashing
	{REG_WEITE, SERIAL_DOWNLOAD_MAGIC_REG, SERIAL_DOWNLOAD_MAGIC},
	{REG_WEITE, SERIAL_DOWNLOAD_SRC_REG, SERIAL_DOWNLOAD_SRC_ADDR},
	{REG_WEITE, SERIAL_DOWNLOAD_TGT_REG, NULL},
	{REG_WEITE, SERIAL_DOWNLOAD_SZ_REG, NULL},
};

#define INIT_LOOP_COUNT		(sizeof(mx21reg_initsys) / sizeof(struct reg_addr_val))
#define SET_MAGIC_FOR_DOWNLOAD()	(mx21reg_initsys[INIT_LOOP_COUNT-4].val = 0)
#define SET_TGT_ADDR_FOR_FLASH(x)	(mx21reg_initsys[INIT_LOOP_COUNT-2].val = x)
#define SET_SIZE_FOR_FLASH(x)	(mx21reg_initsys[INIT_LOOP_COUNT-1].val = x)

int main(int argc, char* argv[])
{
	int port;
	unsigned long download = 0, result;
	char *file_name;
	char *port_name;
	HANDLE portH;
	FILE *fp;
	unsigned long total;
	unsigned long bytes_read = 0;

	if (argc == 1) {
		goto help_msg;
    }
	if (argc != 4 && argc != 5) {
		printf("Wrong number of arguments.\n");
		goto help_msg_short;
	}
    if (parse_cmd_line(argc, argv, &port, &download) != 0) {
		printf("Command parsing error\n");
		goto help_msg_short;
    }

	port_name = argv[1];
	file_name = argv[3];
	if (download >= SDRAM_BASE_ADDR && 
		download < (SDRAM_BASE_ADDR + SDRAM_SIZE)) {
		action = ENUM_DOWNLOAD;
		if (debug) printf("downloading to sdram ...\n");
	} else if (download >= CS0_BASE_ADDR && 
			   download < (CS0_BASE_ADDR + CS0_SIZE)) {
		action = ENUM_NOR;
	} else if (download >= NFC_BASE && 
			   download < (NFC_BASE + NFC_SIZE)) {
		action = ENUM_NAND;
		printf("programing to NAND flash is not supported yet\n");
		printf("nice try :<\n");
		exit (-1);
	} else {
		printf("Unknown address range. Assuming download ...\n");
	}

	// Open the serial port.
	if ((portH = Open_Port(port_name, CBR_115200)) == INVALID_HANDLE_VALUE) {
		printf("Error: %s is in use\n", port_name);
		return -1;
	}
	if (op_header(portH, irom_status, &result) != ROM_OK)
		goto func_out;

	if (debug) printf("status = 0x%08x '%s'\n", result, status_to_string(result));
	switch (action) {
	case ENUM_DOWNLOAD:
		SET_MAGIC_FOR_DOWNLOAD();
		if (config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) != ROM_OK) {
			printf("config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) failed\n");
			goto func_out;
		}
		printf("Downloading to SDRAM at 0x%x via %s. File: %s\n",
			   download, port_name, file_name);
		if (download_file(portH, file_name, download) != ROM_OK) {
			printf("download_file() failed at line %d\n", __LINE__);
			goto func_out;
		}
		// execute
		SET_ADDR(irom_exec, download);
		if (op_header(portH, irom_exec, &result) != ROM_OK) {
			printf("Failed to exec\n");
			goto func_out;
		}
		printf("\nJumping to 0x%08x\n", download);
		if (op_header(portH, irom_status, &result) != ROM_OK)
			goto func_out;
		break;
	case ENUM_NOR:
		SET_TGT_ADDR_FOR_FLASH(download);

		if ((fp = fopen(file_name,"rb")) == NULL) {
			printf("\nUnable to open file: %s\n", file_name);
			return ERR_FILE_NOT_OPEN;
		}

		if ((total = filelength(fileno(fp))) == 0 || total > 0x2000000 /* 32MB max*/) {
			printf("File has invalid size %d.\n", total);
			return ERR_FILE_ZERO_BYTE;
		}
		if (!fp) {
			fclose(fp);
		}
		
		SET_SIZE_FOR_FLASH(total);
		if (config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) != ROM_OK) {
			printf("config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) failed\n");
			goto func_out;
		}

		if (debug) printf("Downloading to SDRAM at 0x%x via %s. File: %s\n",
                          SERIAL_DOWNLOAD_SRC_ADDR, port_name, file_name);
		printf("Downloading\n");
		if (download_file(portH, file_name, SERIAL_DOWNLOAD_SRC_ADDR) != ROM_OK) {
			printf("download_file() failed at line %d\n", __LINE__);
			goto func_out;
		}
              
		if (debug)printf("Downloading .dat to SDRAM at 0x%x via %s. File: %s\n",
                         FLASH_CODE_ADDR, port_name, "./flash_code");
		if (download_file(portH, "./flash_code", FLASH_CODE_ADDR) != ROM_OK) {
			printf("download_file() failed at line %d\n", __LINE__);
			goto func_out;
		}

		// execute
		SET_ADDR(irom_exec, FLASH_CODE_ADDR);
		if (op_header(portH, irom_exec, &result) != ROM_OK) {
			printf("Failed to exec\n");
			goto func_out;
		}
		op_header(portH, irom_status, &result);

		if (PurgeComm(portH, PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR) == 0) {
			printf("PurgeComm() failed\n"); 
			return ROM_ERROR;
		}
		
		Shutdown_Port(portH);
		if ((portH = Open_Port(port_name, CBR_115200)) == INVALID_HANDLE_VALUE) {
			printf("Error: %s is in use\n", port_name);
			return -1;
		}
		printf("\nStart erasing\n");
		while (1) {
			unsigned char c, cc[9];
			printf("."); 
			if (ReadFile(portH, &c, 1, &bytes_read, NULL) == 0) {
				printf("\nReadFile failed at line: %d\n", __LINE__);
				goto func_out;
			}
			if (debug) printf("%c", c);

			if (c == '\n') {
				if (ReadFile(portH, &cc, 8, &bytes_read, NULL) == 0) {
					printf("\nReadFile failed at line: %d\n", __LINE__);
					goto func_out;
				}
				cc[8] = 0;
				if (debug) printf("cc=%s\n", cc);
				if (memcmp(cc, "BEADDEAD", 8) == 0) {
					printf("\nErase failed\n");
					goto func_out;
				} else if (memcmp(cc, "BEADBEEF", 8) == 0) {
					printf("\nErase ok. Start programming\n");
				} else if (memcmp(cc, "BEADFEEF", 8) == 0) {
					printf("\nProgram failed\n");
					goto func_out;
				} else if (memcmp(cc, "BEADCEEF", 8) == 0) {
					printf("\nProgram ok\n");
					goto func_out;
				}
			}

		}

		break;
	case ENUM_NAND:
		break;
	}

func_out:
	if (!fp) fclose(fp);
    Shutdown_Port(portH);

	exit (0);

help_msg:
	PRINT_HELP_MSG(argv[0]);
	exit (-1);
help_msg_short:
	printf("Type %s without argument for help\n", argv[0]);
	exit(-1);

}

/*!
 * Open a serial port for reading or writing.
 */
HANDLE Open_Port(char* pcCommPort, int baud)
{
	HANDLE hCom;
	if (debug) printf("\nOpen_Port for RW Opening = %s \n",pcCommPort);
	hCom = CreateFile (pcCommPort,						// Pointer to the name of the port
                       GENERIC_READ | GENERIC_WRITE,	// Access (read-write) mode
                       0,								// Share mode
                       NULL,							// Pointer to the security attribute
                       OPEN_EXISTING,					// How to open the port
                       0,								// Port attributes
                       NULL);							// Handle to port with attribute

	if (hCom == INVALID_HANDLE_VALUE) {
		// Handle the error.
		printf ("CreateFile failed with error %d.\n", GetLastError());
		return INVALID_HANDLE_VALUE;
	}
	else {
		if (debug) printf("Setting up port %s with baud=%d\n", pcCommPort, baud);
		if (Setup_Port(hCom, baud) == 0) {
			if (debug) printf ("Serial port %s successfully reconfigured.\n", pcCommPort);
		} else
			return INVALID_HANDLE_VALUE;
	}

	return hCom;
}
/*!
 * Close a port with a serial or parallel port printer.
 */
void Shutdown_Port(HANDLE portH)
{
	if (portH != NULL)
		CloseHandle(portH);
}

/*!
 * Setup the serial or parallel port currently selected with specific baud rate
 */
int Setup_Port(HANDLE hCom, int baud)
{
	DCB  dcb;
	COMMTIMEOUTS CommTimeouts;

	// Build on the current configuration, and skip setting the size
	// of the input and output buffers with SetupComm.

⌨️ 快捷键说明

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