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

📄 mx21serial.cpp

📁 Redboot, boot-loader of Linux for Freescale ARM family.
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	if (GetCommState(hCom, &dcb) == 0) {
	   printf ("GetCommState failed with error %d.\n", GetLastError());
	   return (2);
	}
    
	// Fill in DCB: 115,200 bps, 8 data bits, no parity, and 1 stop bit.
	dcb.BaudRate = baud;     // set the baud rate
	dcb.ByteSize = 8;             // data size, xmit, and rcv
	dcb.Parity = NOPARITY;        // no parity bit
	dcb.StopBits = ONESTOPBIT;    // one stop bit

	if (SetCommState(hCom, &dcb) == 0) {
	   // Handle the error.
	   printf ("SetCommState failed with error %d.\n", GetLastError());
	   return (3);
	}

	//Communication timeouts are optional but can be set similarly to DCB values
	//This will prevent the program from hanging should the port does not respond.
	if (GetCommTimeouts (hCom, &CommTimeouts) == 0) {
		printf("Failed at GetCommTimeouts()\n");
		return 4;
	}
	if (debug) printf("\
		   CommTimeouts.ReadIntervalTimeout = %d\n\
		   CommTimeouts.ReadTotalTimeoutConstant = %d\n\
		   CommTimeouts.ReadTotalTimeoutMultiplier = %d\n\
		   CommTimeouts.WriteTotalTimeoutConstant = %d\n\
		   CommTimeouts.WriteTotalTimeoutMultiplier = %d\n",
			CommTimeouts.ReadIntervalTimeout,
			CommTimeouts.ReadTotalTimeoutConstant,
			CommTimeouts.ReadTotalTimeoutMultiplier,
			CommTimeouts.WriteTotalTimeoutConstant,
			CommTimeouts.WriteTotalTimeoutMultiplier);
           
	CommTimeouts.ReadIntervalTimeout = 50;
	CommTimeouts.ReadTotalTimeoutConstant = 100;
	CommTimeouts.ReadTotalTimeoutMultiplier = 10;
	CommTimeouts.WriteTotalTimeoutConstant = 100;
	CommTimeouts.WriteTotalTimeoutMultiplier = 10;

	if (SetCommTimeouts (hCom, &CommTimeouts) == 0) {
		printf("Failed to SetCommTimeouts()\n");
		return 5;
	}

	return 0;
}

/*
 * Convert the error status code from the i.mx21 bootstrap to a string
 */
char *status_to_string(unsigned long status)
{
	struct status_decode *decode;
	
	decode = &status_codes[0];
	while (!(decode->description == 0 && decode->code == 0)) {
		if (decode->code == status) {
			return decode->description;
		}
		decode++;
	}
	
	return "unknown";
}

void PRINT_HELP_MSG(char* s)
{
	printf("This Windows program downloads a file to a specified memory \n\
location on the MX21ADS board via a PC COM port using internal \n\
UART1 on the ADS board. Note: \n\
1. If the memory location is within the NOR flash range, then it will try \n\
   to program the file into the NOR flash. (NOR flash base is 0xC8000000) \n\
2. If the memory location is within the NAND flash range, then it will try \n\
   to program the file into the NAND flash. (NAND flash base is 0xDF003000)\n\
3. If the memory location is within the SDRAM, it will then jump to that \n\
   location after downloading the file. (SDRAM base is 0xC0000000)\n");

	printf("\nSyntax:\n");
	printf("   %s <com port> <address> <file name>\n", s);
	printf("\nExample:\n");
	printf("<1> %s COM1 0xC0000000 test.bin \n", s);
	printf("    -- download test.bin to the beginning of SDRAM\n");
	printf("<2> %s COM1 0xC8000000 test.bin \n", s);
	printf("    -- program test.bin to the beginning of NOR flash\n");
	printf("<3> %s COM1 0xDF003000 test.bin \n", s);
	printf("    -- program test.bin to the beginning of NAND flash (skip bad blocks)\n");
}

int parse_cmd_line(int argc, char* argv[], int *p_num, unsigned long *download)
{
    int  val1, port;
	unsigned long addr = 0;
    char *ptr;

	// Check for COM port
	if ((argv[1][0] != 'C' && argv[1][0] != 'c') || (argv[1][1] != 'O' && argv[1][1] != 'o') ||
		(argv[1][2] != 'M' && argv[1][2] != 'm') || argv[1][3] == '\0') {
		printf("Use 'COM1', 'COM2', ...\n");
		return (__LINE__);
	}
	ptr = &argv[1][3];
	while ((val1 = *ptr++) != '\0') {
		if (val1 < '0' || val1 > '9') {
			printf("Wrong port number.\n");
            return (__LINE__);
		}
	}
	port = atoi(&(argv[1][3]));

	// Check for download address
	if (argv[2][0] != '0' || argv[2][1] != 'x') {
		printf("Wrong address, use hex format: 0x.... instead\n");
        return (__LINE__);
	}
	ptr = &argv[2][2];
	while ((val1 = *ptr++) != '\0') {
		addr *= 16;
		if (val1 >= 'a' && val1 <= 'f')
			addr += val1 - 'a' + 10;
		else if (val1 >= 'A' && val1 <= 'F')
			addr += val1 - 'A' + 10;
		else if (val1 >= '0' && val1 <= '9')
			addr += val1 - '0';
		else {
			printf("Wrong hex value for address \n");
            return (__LINE__);
		}
	}
	*download = addr;
	if (argc == 5) {
		if (argv[4][0] == '-' && argv[4][1] == 'd')
			debug = 1;
	}

    return 0;
}

/*!
 * Send 16byte operation header to mx21 for various operations
 * @param handle	com port handle
 * @param header	16-byte command header
 * @param result	returned code when reading back the status after cmd is sent
 * @return	ROM_OK if successful; ROM_ERROR otherwise.
 */
int op_header(HANDLE handle, unsigned char* header, unsigned long *result)
{
	unsigned long byte_count, response[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	DWORD dw, bytes_sent;
    LPVOID lpMsgBuf;

    if (PurgeComm(handle, PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR) == 0) {
		printf("PurgeComm() failed\n"); 
		return ROM_ERROR;
	}

	if (WriteFile(handle, header, 16, &bytes_sent, NULL) == 0 ||
		bytes_sent != 16) {
        printf("Failed to write cmd header 0x%x, bytes_written=%d\n", GET_CMD(header), bytes_sent);
        return ROM_ERROR;
    }
	if (debug) printf("GET_CMD(header)=%04x\n", GET_CMD(header));
	
	switch (GET_CMD(header)) {
	case CMD_STATUS:
		if (ReadFile(handle, (unsigned char*)response, 4, &byte_count, NULL) == 0 ||
			byte_count != 4) {
			if (debug) {
				printf ("CMD_STATUS: ReadFile failed with error %d.\n", dw=GetLastError());
				printf("Failed to get status for cmd 0x%x. result=0x%x, bytes_read=%d\n", 
							GET_CMD(header), response[0], byte_count);
				FormatMessage(
					FORMAT_MESSAGE_ALLOCATE_BUFFER | 
					FORMAT_MESSAGE_FROM_SYSTEM,
					NULL,
					dw,
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
					(LPTSTR) &lpMsgBuf,
					0, NULL );

				printf("failed with error %d: %s", dw, lpMsgBuf); 
			}
			return ROM_ERROR;
		}
		break;
	case CMD_DOWNLOAD:
		response[0] = 0;
		// have to ignore the return value since it always returns 0 (error)
		ReadFile(handle, (unsigned char*)response, 4, &byte_count, NULL);
		if (byte_count != 4 || (response[0] != DEVELOPMENT_PART &&
			response[0] != PRODUCTION_PART)) {
			printf ("CMD_DOWNLOAD: ReadFile failed with error %d.\n", GetLastError());
			printf("Failed to get status for cmd 0x%x. result=0x%x, bytes_read=%d\n", 
				   GET_CMD(header), response[0], byte_count);
			return ROM_ERROR;
		}
		break;
	case CMD_READ:
		/* Read write complete acknowledge */
		if (ReadFile(handle, (unsigned char*)response, 8, &byte_count, NULL) == 0 ||
			byte_count != 8) {
			printf("Failed to read 0x%x. resp1=0x%x resp2=0x%x bytes_read=%d\n", 
				   GET_CMD(header), response[0], response[1], byte_count);
			return ROM_ERROR;
		}
		break;
	case CMD_WRITE:
		/* Read write complete acknowledge */
		if (ReadFile(handle, response, 8, &byte_count, NULL) == 0 ||
			byte_count != 8) {
			printf("Failed to write 0x%x. resp_b=0x%x, resp_c=0x%x, bytes_read=%d\n", 
				   GET_CMD(header), response[0], response[1], byte_count);
			return ROM_ERROR;
		}
		if (response[1] != WRITE_COMPLETE) {
			printf("Failed: 0x%x. resp_b=0x%x, resp_c=0x%x, bytes_read=%d\n", 
				   GET_CMD(header), response[0], response[1], byte_count);
			return ROM_ERROR;
		}
		break;
	}
	if (debug) printf("resp1=0x%08x resp2=0x%08x\n", response[0], response[1]);
	*result = response[0];
	return ROM_OK;   
}

/*!
 * Download a file via a com port on the target
 * @param handle	com port handle
 * @param f_name	file name to be downloaded
 * @param addr		target address to be downloaded
 * @return 			ROM_OK if successful
 */
int download_file(HANDLE handle, char *f_name, unsigned long addr)
{
	FILE *fp;
	unsigned long byte_count, result, sz_sent, i = 0, total;
	
	if ((fp = fopen(f_name,"rb")) == NULL) {
		printf("\nUnable to open file: %s\n", f_name);
		return ERR_FILE_NOT_OPEN;
	}

	if ((total = filelength(fileno(fp))) == 0 || total > 0x2000000 /* 32MB max*/) {
		printf("Zero byte file.\n");
		return ERR_FILE_ZERO_BYTE;
	}
	while ((byte_count = fread(scratch_buf, sizeof(char), DATA_LEN, fp)) != 0) {
		// send byte_count bytes
		SET_ADDR(irom_download, addr);
		SET_COUNT(irom_download, byte_count);
		if (debug) 
			printf("addr=0x%x, byte_count=0x%x\n", addr, byte_count);
		else {
			printf("."); 
		}

		if (op_header(handle, irom_download, &result) != ROM_OK)
			return ROM_ERROR;
		// send data out to serial port
		if (WriteFile(handle, scratch_buf, byte_count, &sz_sent, NULL) == 0 ||
			sz_sent != byte_count) {
			printf("Failed to download. sz_sent=%d\n", sz_sent);
			return ROM_ERROR;
		}

		if (byte_count < DATA_LEN)	// last buffer
			break;

		addr += byte_count;
	}
	if (debug) printf("\nFinish downloading %d bytes\n", total);

	if (!fp) {
		fclose(fp);
	}
	return ROM_OK;
}

/*!
 * Send read/write register command
 * @param handle	com port handle
 * @param p			pointer to an array of the register profile for read/write with values
 * @param count		number of entries in the array
 * @return			ROM_OK if successful; ROM_ERROR otherwise
 */
int config_reg(HANDLE handle, struct reg_addr_val p[], unsigned long count)
{
	unsigned long result, i;

	if (debug) printf("INIT_LOOP_COUNT=%d\n", INIT_LOOP_COUNT);

	for (i = 0; i < INIT_LOOP_COUNT; i++) {
		if (p[i].r_w == REG_READ) {
			SET_ADDR(irom_readl, p[i].addr);
			if (op_header(handle, irom_readl, &result) != 0) {
				printf("Error at line: %d\n", __LINE__);
				return ROM_ERROR;
			}
		} else {
			SET_ADDR(irom_writel, p[i].addr);
			SET_DATA(irom_writel, p[i].val); 
			if (op_header(handle, irom_writel, &result) != 0) {
				printf("Error at line: %d\n", __LINE__);
				return ROM_ERROR;
			}
		}
	}
	return ROM_OK;
}

⌨️ 快捷键说明

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