📄 mx21serial.cpp
字号:
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 + -